]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/blobdiff - src/arch/sys_arch.c
Remove inline from non-static functions
[pes-rpp/rpp-lwip.git] / src / arch / sys_arch.c
index 3724d0b787b5bf3f8395e9af7c244362e3e6c424..726e2dd77dd7bfb9f20318c0d9bd102dfd5819d7 100644 (file)
 
 /* For mutexes you can just set option in opt.h/lwipopts.h LWIP_COMPAT_MUTEX,
  * which is using defined semaphores. This is basicaly doing the same thing. */
+#if !LWIP_COMPAT_MUTEX
 /* Create a new mutex */
 err_t sys_mutex_new(sys_mutex_t *mutex)
 {
        *mutex = xSemaphoreCreateMutex();
-       if(mutex != NULL)return ERR_OK;
+       if(*mutex != NULL)return ERR_OK;
     return ERR_MEM;
 }
 /* locks a mutex */
-void inline sys_mutex_lock(sys_mutex_t *mutex)
+void sys_mutex_lock(sys_mutex_t *mutex)
 {
-       xSemaphoreTake(*mutex,0);
+       xSemaphoreTake(*mutex,portMAX_DELAY); /* block time changed from 0 to portMAX_DELAY -- it might break timers! - just testing stability */
 }
 /* unlocks a mutex */
-void inline sys_mutex_unlock(sys_mutex_t *mutex)
+void sys_mutex_unlock(sys_mutex_t *mutex)
 {
        xSemaphoreGive(*mutex);
 }
 /* frees memory space formerly taken by mutex */
-void inline sys_mutex_free(sys_mutex_t *mutex)
+void sys_mutex_free(sys_mutex_t *mutex)
 {
        vSemaphoreDelete(*mutex);
 }
+#endif
 
 /* creates a new semaphore */
 err_t sys_sem_new(sys_sem_t *sem, u8_t count)
 {
     *sem = xSemaphoreCreateCounting( SEMPHR_MAX_CNT, count); /* it's supposedly possible to use vSemaphoreCreateBinary */
-    if(sem != NULL)return ERR_OK;
+    if(*sem != NULL)return ERR_OK;
     return ERR_MEM;
 }
 /* signals a semaphore */
-void inline sys_sem_signal(sys_sem_t *sem)
+void sys_sem_signal(sys_sem_t *sem)
 {
        xSemaphoreGive(*sem);
 }
@@ -88,12 +90,19 @@ void inline sys_sem_signal(sys_sem_t *sem)
 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
 {
        portTickType ticksBeforeSemphr = xTaskGetTickCount();
-    if(xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdFALSE) /* note that it is important for the semaphores to return an accurate count of elapsed milliseconds, since they are used to schedule timers in lwIP */
-       return SYS_ARCH_TIMEOUT;
+       if(timeout == 0)
+       {
+               xSemaphoreTake( *sem, portMAX_DELAY );
+       }
+       else
+       {
+               if(xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdFALSE) /* note that it is important for the semaphores to return an accurate count of elapsed milliseconds, since they are used to schedule timers in lwIP */
+                       return SYS_ARCH_TIMEOUT;
+       }
     return ( (xTaskGetTickCount() - ticksBeforeSemphr) / portTICK_RATE_MS ); /* return time spent waiting for the semaphore - u can use xTaskGetTickCount() */
 }
 /* deletes a semaphore */
-void inline sys_sem_free(sys_sem_t *sem)
+void sys_sem_free(sys_sem_t *sem)
 {
        vSemaphoreDelete(*sem);
 }
@@ -102,27 +111,27 @@ void inline sys_sem_free(sys_sem_t *sem)
 err_t sys_mbox_new(sys_mbox_t *mbox, int size)
 {
        *mbox = xQueueCreate( size, sizeof( MBOX_PTR_TYPE ) );
-       if(mbox == 0)return ERR_MEM;
+       if(*mbox == NULL)return ERR_MEM;
        return ERR_OK;
 }
 /* posts the "msg" to the mailbox, blocks if mbox full */
-void inline sys_mbox_post(sys_mbox_t *mbox, void *msg)
+void sys_mbox_post(sys_mbox_t *mbox, void *msg)
 {
-       while(xQueueSendToBack(*mbox, msg, portMAX_DELAY) == errQUEUE_FULL);
+       while(xQueueSendToBack(*mbox, &msg, portMAX_DELAY) == errQUEUE_FULL);
 }
 /* returns ERR_MEM if mailbox is full, ERR_OK if "msg" is posted */
 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
 {
 #if TRYPOST_ISR_SAFE
        signed portBASE_TYPE *pxHigherPriorityTaskWoken;
-       if(xQueueSendToBackFromISR( *mbox, msg, pxHigherPriorityTaskWoken ) == errQUEUE_FULL)
+       if(xQueueSendToBackFromISR( *mbox, &msg, pxHigherPriorityTaskWoken ) == errQUEUE_FULL)
 #else
-    if(xQueueSendToBack(*mbox, msg, 0) == errQUEUE_FULL)
+    if(xQueueSendToBack(*mbox, &msg, 0) == errQUEUE_FULL)
 #endif
                return ERR_MEM;
        return ERR_OK;
 }
-/* TODO: message which arrives may be NULL */
+/* message which arrives may be NULL */
 /* blocks the thread until a message arrives in the mailbox or timeout expires */
 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
 {
@@ -138,7 +147,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
        }
        return ( (xTaskGetTickCount() - ticksBeforeFetch) / portTICK_RATE_MS ); /* return time spent waiting for the space in the mailbox */
 }
-/* if message is not present immediately returns SYS_MBOX_EMPTY, on success returns 0 */
+/* if message is not present immediately returns SYS_MBOX_EMPTY, on success returns 0 ms */
 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
 {
 #if TRYFETCH_ISR_SAFE
@@ -151,7 +160,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
        return 0; /* we waited 0ms */
 }
 /* deletes a mbox */
-void inline sys_mbox_free(sys_mbox_t *mbox)
+void sys_mbox_free(sys_mbox_t *mbox)
 {
        vQueueDelete(*mbox);
 }
@@ -167,13 +176,20 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
 #endif /* NO_SYS */
 
 
-/* TODO: research on what put to sys_init() >>
- * void sys_init(void). lwIP system initialization. This function is called before the any other
+#if SYS_ARCH_SEMPHR_PROTECT
+sys_mutex_t sys_arch_prot_semphr;
+xTaskHandle protectedTask = NULL;
+#endif /* SYS_ARCH_SEMPHR_PROTECT */
+
+/* void sys_init(void). lwIP system initialization. This function is called before the any other
  * sys_arch-function is called and is meant to be used to initialize anything that has to be up and
  * running for the rest of the functions to work. for example to set up a pool of semaphores.
  * This function is called from lwip_init() */
 void sys_init(void) /* initialize sys_arch layer */
 {
+#if SYS_ARCH_SEMPHR_PROTECT
+       sys_mutex_new(&sys_arch_prot_semphr);
+#endif /* SYS_ARCH_SEMPHR_PROTECT */
 }
 
 u32_t sys_jiffies(void)
@@ -192,7 +208,7 @@ u32_t sys_now(void)
 
        }
        */
-       /* for configTICK_RATE_Hz = 1000; when GetTickCount() fce returns 64-bit unsigned type it holds
+       /* for configTICK_RATE_Hz = 1000; when GetTickCount() fnc returns 64-bit unsigned type it holds
        about half billion years, for unsigned 32-bit type just about an hour ; ((((2³²)÷1000)÷configTICK_RATE_HZ)÷3600)÷24 */
        /*return (xTaskGetTickCount()*1000 / configTICK_RATE_HZ) ;*/
 
@@ -201,10 +217,13 @@ u32_t sys_now(void)
 
 #if SYS_LIGHTWEIGHT_PROT
 
+#if !SYS_ARCH_SEMPHR_PROTECT
 unsigned int IntMasterStatusGet        (void)
 {
-    return 0;//(unsigned int)(0xC0 & _get_CPSR());
+    return (unsigned int)(0xC0 & _get_CPSR());
 }
+#endif /* !SYS_ARCH_SEMPHR_PROTECT */
+
 /**
  * This function is used to lock access to critical sections when lwipopt.h
  * defines SYS_LIGHTWEIGHT_PROT. It disables interrupts and returns a value
@@ -215,11 +234,37 @@ unsigned int IntMasterStatusGet   (void)
  */
 sys_prot_t sys_arch_protect(void)
 {
+#if !SYS_ARCH_SEMPHR_PROTECT
     sys_prot_t status;
     status = (IntMasterStatusGet() & 0xFF);
 
     _disable_IRQ();
+    /* while interrupts ethernet related or interrupt for context switch don't use FIQ, we dont need to disable it */
+/*    _disable_FIQ(); */
     return status;
+#else /* !SYS_ARCH_SEMPHR_PROTECT */
+    taskENTER_CRITICAL();
+    if(protectedTask == xTaskGetCurrentTaskHandle()){ /* if protected task calls nested sys_arch_protect we let it know that it was protected already */
+        taskEXIT_CRITICAL();
+        return TRUE;
+    } else {
+       while(1)
+       {
+               sys_mutex_lock(&sys_arch_prot_semphr);
+               if(protectedTask == NULL)
+               {
+               protectedTask = xTaskGetCurrentTaskHandle();
+               break;
+               }
+               else
+               {
+                       sys_mutex_unlock(&sys_arch_prot_semphr); /* we shouldn't get here ever */
+               }
+       }
+    }
+    taskEXIT_CRITICAL();
+    return FALSE;
+#endif /* !SYS_ARCH_SEMPHR_PROTECT */
 }
 
 /**
@@ -233,11 +278,25 @@ sys_prot_t sys_arch_protect(void)
  */
 void sys_arch_unprotect(sys_prot_t lev)
 {
+#if !SYS_ARCH_SEMPHR_PROTECT
     /* Only turn interrupts back on if they were originally on when the matching
        sys_arch_protect() call was made. */
     if((lev & 0x80) == 0) {
         _enable_IRQ();
     }
+    /* while interrupts ethernet related or interrupt for context switch don't use FIQ, we dont need to protect against it */
+/*    if((lev & 0x40) == 0) {
+        _enable_FIQ();
+    }*/
+#else /* !SYS_ARCH_SEMPHR_PROTECT */
+    taskENTER_CRITICAL();
+    if(!lev) /* if task wasn't already protected when sys_arch_protect() was called, unprotect it now */
+    {
+       protectedTask = NULL;
+       sys_mutex_unlock(&sys_arch_prot_semphr);
+    }
+    taskEXIT_CRITICAL();
+#endif /* !SYS_ARCH_SEMPHR_PROTECT */
 }
 
 #endif /* SYS_LIGHTWEIGHT_PROT */