3 * System Architecture support routines for HDK devices.
8 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
11 * Redistribution and use in source and binary forms, with or without modification,
12 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 * This file is part of the lwIP TCP/IP stack.
35 * Author: Adam Dunkels <adam@sics.se>
39 /* Copyright (c) 2010 Texas Instruments Incorporated */
42 #include "arch/sys_arch.h"
47 /* DETAILS: ./lwip/doc/sys_arch.txt
48 * ./lwip/src/include/lwip/sys.h */
50 /* For mutexes you can just set option in opt.h/lwipopts.h LWIP_COMPAT_MUTEX,
51 * which is using defined semaphores. This is basicaly doing the same thing. */
52 #if !LWIP_COMPAT_MUTEX
53 /* Create a new mutex */
54 err_t sys_mutex_new(sys_mutex_t *mutex)
56 *mutex = xSemaphoreCreateMutex();
57 if(*mutex != NULL)return ERR_OK;
61 void inline sys_mutex_lock(sys_mutex_t *mutex)
63 xSemaphoreTake(*mutex,portMAX_DELAY); /* block time changed from 0 to portMAX_DELAY -- it might break timers! - just testing stability */
66 void inline sys_mutex_unlock(sys_mutex_t *mutex)
68 xSemaphoreGive(*mutex);
70 /* frees memory space formerly taken by mutex */
71 void inline sys_mutex_free(sys_mutex_t *mutex)
73 vSemaphoreDelete(*mutex);
77 /* creates a new semaphore */
78 err_t sys_sem_new(sys_sem_t *sem, u8_t count)
80 *sem = xSemaphoreCreateCounting( SEMPHR_MAX_CNT, count); /* it's supposedly possible to use vSemaphoreCreateBinary */
81 if(*sem != NULL)return ERR_OK;
84 /* signals a semaphore */
85 void inline sys_sem_signal(sys_sem_t *sem)
89 /* blocks thread while waiting for the semaphore */
90 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
92 portTickType ticksBeforeSemphr = xTaskGetTickCount();
95 xSemaphoreTake( *sem, portMAX_DELAY );
99 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 */
100 return SYS_ARCH_TIMEOUT;
102 return ( (xTaskGetTickCount() - ticksBeforeSemphr) / portTICK_RATE_MS ); /* return time spent waiting for the semaphore - u can use xTaskGetTickCount() */
104 /* deletes a semaphore */
105 void inline sys_sem_free(sys_sem_t *sem)
107 vSemaphoreDelete(*sem);
110 /* creates an empty mailbox for maximum "size" elements */
111 err_t sys_mbox_new(sys_mbox_t *mbox, int size)
113 *mbox = xQueueCreate( size, sizeof( MBOX_PTR_TYPE ) );
114 if(*mbox == NULL)return ERR_MEM;
117 /* posts the "msg" to the mailbox, blocks if mbox full */
118 void inline sys_mbox_post(sys_mbox_t *mbox, void *msg)
120 while(xQueueSendToBack(*mbox, &msg, portMAX_DELAY) == errQUEUE_FULL);
122 /* returns ERR_MEM if mailbox is full, ERR_OK if "msg" is posted */
123 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
126 signed portBASE_TYPE *pxHigherPriorityTaskWoken;
127 if(xQueueSendToBackFromISR( *mbox, &msg, pxHigherPriorityTaskWoken ) == errQUEUE_FULL)
129 if(xQueueSendToBack(*mbox, &msg, 0) == errQUEUE_FULL)
134 /* TODO: message which arrives may be NULL */
135 /* blocks the thread until a message arrives in the mailbox or timeout expires */
136 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
138 portTickType ticksBeforeFetch = xTaskGetTickCount();
141 while(xQueueReceive( *mbox, msg, portMAX_DELAY ) == pdFALSE);
145 if(xQueueReceive( *mbox, msg, timeout / portTICK_RATE_MS ) == pdFALSE)
146 return SYS_ARCH_TIMEOUT;
148 return ( (xTaskGetTickCount() - ticksBeforeFetch) / portTICK_RATE_MS ); /* return time spent waiting for the space in the mailbox */
150 /* if message is not present immediately returns SYS_MBOX_EMPTY, on success returns 0 ms */
151 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
153 #if TRYFETCH_ISR_SAFE
154 signed portBASE_TYPE *pxTaskWoken;
155 if(xQueueReceiveFromISR( *mbox, msg, pxTaskWoken ) == pdFALSE)
157 if(xQueueReceive(*mbox, msg, 0) == pdFALSE)
159 return SYS_MBOX_EMPTY;
160 return 0; /* we waited 0ms */
163 void inline sys_mbox_free(sys_mbox_t *mbox)
168 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
170 xTaskHandle *pvCreatedTask = NULL;
171 if(xTaskCreate(thread, (const signed char *) name, (unsigned short)stacksize, arg, prio, pvCreatedTask) != pdPASS)
172 return NULL; /* lwIP doesn't specify, how should be informed that thread creation failed */
173 return pvCreatedTask;
179 /* TODO: research on what put to sys_init() >>
180 * void sys_init(void). lwIP system initialization. This function is called before the any other
181 * sys_arch-function is called and is meant to be used to initialize anything that has to be up and
182 * running for the rest of the functions to work. for example to set up a pool of semaphores.
183 * This function is called from lwip_init() */
184 void sys_init(void) /* initialize sys_arch layer */
188 u32_t sys_jiffies(void)
190 return (u32_t) xTaskGetTickCount();
193 /* TODO: consider overflowing */
196 return (u32_t) xTaskGetTickCount(); /* this works on condition that portTICK_RATE_MS is 1 */
198 portTickType currentTicks = xTaskGetTickCount();
199 static portTickType previousTickCount;
200 if(previousTickCount>currentTicks){
204 /* for configTICK_RATE_Hz = 1000; when GetTickCount() fce returns 64-bit unsigned type it holds
205 about half billion years, for unsigned 32-bit type just about an hour ; ((((2³²)÷1000)÷configTICK_RATE_HZ)÷3600)÷24 */
206 /*return (xTaskGetTickCount()*1000 / configTICK_RATE_HZ) ;*/
211 #if SYS_LIGHTWEIGHT_PROT
213 unsigned int IntMasterStatusGet (void)
215 return (unsigned int)(0xC0 & _get_CPSR());
218 * This function is used to lock access to critical sections when lwipopt.h
219 * defines SYS_LIGHTWEIGHT_PROT. It disables interrupts and returns a value
220 * indicating the interrupt enable state when the function entered. This
221 * value must be passed back on the matching call to sys_arch_unprotect().
223 * @return the interrupt level when the function was entered.
225 sys_prot_t sys_arch_protect(void)
228 status = (IntMasterStatusGet() & 0xFF);
235 sys_prot_t sys_arch_protect(void)
238 status = (IntMasterStatusGet() & 0xFF);
246 * This function is used to unlock access to critical sections when lwipopt.h
247 * defines SYS_LIGHTWEIGHT_PROT. It enables interrupts if the value of the lev
248 * parameter indicates that they were enabled when the matching call to
249 * sys_arch_protect() was made.
251 * @param lev is the interrupt level when the matching protect function was
254 void sys_arch_unprotect(sys_prot_t lev)
256 /* Only turn interrupts back on if they were originally on when the matching
257 sys_arch_protect() call was made. */
258 if((lev & 0x80) == 0) {
261 if((lev & 0x40) == 0) {
266 void sys_arch_unprotect(sys_prot_t lev)
268 /* Only turn interrupts back on if they were originally on when the matching
269 sys_arch_protect() call was made. */
270 /* if((lev & 0xFF) == 0) {
276 #endif /* SYS_LIGHTWEIGHT_PROT */