local fork (temporary)

Dependents:   VodafoneUSBModem_bleedingedge2

Fork of lwip-sys by mbed official

Committer:
emilmont
Date:
Fri Jun 22 11:12:52 2012 +0000
Revision:
1:a7366e261ca3
Parent:
0:762278923909
Child:
4:dd37867293e7
First lwip operating system implementation based on CMIS-RTOS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 1:a7366e261ca3 1 /* Copyright (C) 2012 mbed.org, MIT License
emilmont 1:a7366e261ca3 2 *
emilmont 1:a7366e261ca3 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
emilmont 1:a7366e261ca3 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
emilmont 1:a7366e261ca3 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
emilmont 1:a7366e261ca3 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
emilmont 1:a7366e261ca3 7 * furnished to do so, subject to the following conditions:
emilmont 1:a7366e261ca3 8 *
emilmont 1:a7366e261ca3 9 * The above copyright notice and this permission notice shall be included in all copies or
emilmont 1:a7366e261ca3 10 * substantial portions of the Software.
emilmont 1:a7366e261ca3 11 *
emilmont 1:a7366e261ca3 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
emilmont 1:a7366e261ca3 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
emilmont 1:a7366e261ca3 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
emilmont 1:a7366e261ca3 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
emilmont 1:a7366e261ca3 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
emilmont 1:a7366e261ca3 17 */
emilmont 1:a7366e261ca3 18 #include <string.h>
emilmont 1:a7366e261ca3 19
emilmont 1:a7366e261ca3 20 /* mbed includes */
emilmont 1:a7366e261ca3 21 #include "error.h"
emilmont 1:a7366e261ca3 22 #include "mbed_interface.h"
emilmont 1:a7366e261ca3 23
emilmont 1:a7366e261ca3 24 /* lwIP includes. */
emilmont 1:a7366e261ca3 25 #include "lwip/opt.h"
emilmont 1:a7366e261ca3 26 #include "lwip/debug.h"
emilmont 1:a7366e261ca3 27 #include "lwip/def.h"
emilmont 1:a7366e261ca3 28 #include "lwip/sys.h"
emilmont 1:a7366e261ca3 29 #include "lwip/mem.h"
emilmont 1:a7366e261ca3 30
emilmont 1:a7366e261ca3 31 #if NO_SYS==1
emilmont 1:a7366e261ca3 32 #include "cmsis.h"
emilmont 1:a7366e261ca3 33
emilmont 1:a7366e261ca3 34 /* Saved total time in ms since timer was enabled */
emilmont 1:a7366e261ca3 35 static volatile u32_t systick_timems;
emilmont 1:a7366e261ca3 36
emilmont 1:a7366e261ca3 37 /* Enable systick rate and interrupt */
emilmont 1:a7366e261ca3 38 void SysTick_Init(void) {
emilmont 1:a7366e261ca3 39 if (SysTick_Config(SystemCoreClock / 1000)) {
emilmont 1:a7366e261ca3 40 while (1); /* Capture error */
emilmont 1:a7366e261ca3 41 }
emilmont 1:a7366e261ca3 42 }
emilmont 1:a7366e261ca3 43
emilmont 1:a7366e261ca3 44 /** \brief SysTick IRQ handler and timebase management
emilmont 1:a7366e261ca3 45 *
emilmont 1:a7366e261ca3 46 * This function keeps a timebase for the sysTick that can be
emilmont 1:a7366e261ca3 47 * used for other functions. It also calls an external function
emilmont 1:a7366e261ca3 48 * (SysTick_User) that must be defined outside this handler.
emilmont 1:a7366e261ca3 49 */
emilmont 1:a7366e261ca3 50 void SysTick_Handler(void) {
emilmont 1:a7366e261ca3 51 systick_timems++;
emilmont 1:a7366e261ca3 52 }
emilmont 1:a7366e261ca3 53
emilmont 1:a7366e261ca3 54 /* Delay for the specified number of milliSeconds */
emilmont 1:a7366e261ca3 55 void osDelay(uint32_t ms) {
emilmont 1:a7366e261ca3 56 uint32_t to = ms + systick_timems;
emilmont 1:a7366e261ca3 57 while (to > systick_timems);
emilmont 1:a7366e261ca3 58 }
emilmont 1:a7366e261ca3 59
emilmont 1:a7366e261ca3 60 /* Returns the current time in mS. This is needed for the LWIP timers */
emilmont 1:a7366e261ca3 61 u32_t sys_now(void) {
emilmont 1:a7366e261ca3 62 return (u32_t) systick_timems;
emilmont 1:a7366e261ca3 63 }
emilmont 1:a7366e261ca3 64
emilmont 1:a7366e261ca3 65 #else
emilmont 1:a7366e261ca3 66 /* CMSIS-RTOS implementation of the lwip operating system abstraction */
emilmont 1:a7366e261ca3 67 #include "arch/sys_arch.h"
emilmont 1:a7366e261ca3 68
emilmont 1:a7366e261ca3 69 // #include "us_ticker_api.h" -> Not yet public
emilmont 1:a7366e261ca3 70 extern uint32_t us_ticker_read(void);
emilmont 1:a7366e261ca3 71
emilmont 1:a7366e261ca3 72 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 73 * Routine: sys_mbox_new
emilmont 1:a7366e261ca3 74 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 75 * Description:
emilmont 1:a7366e261ca3 76 * Creates a new mailbox
emilmont 1:a7366e261ca3 77 * Inputs:
emilmont 1:a7366e261ca3 78 * sys_mbox_t mbox -- Handle of mailbox
emilmont 1:a7366e261ca3 79 * int queue_sz -- Size of elements in the mailbox
emilmont 1:a7366e261ca3 80 * Outputs:
emilmont 1:a7366e261ca3 81 * err_t -- ERR_OK if message posted, else ERR_MEM
emilmont 1:a7366e261ca3 82 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 83 err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) {
emilmont 1:a7366e261ca3 84 if (queue_sz > MB_SIZE)
emilmont 1:a7366e261ca3 85 error("sys_mbox_new size error\n");
emilmont 1:a7366e261ca3 86
emilmont 1:a7366e261ca3 87 #ifdef CMSIS_OS_RTX
emilmont 1:a7366e261ca3 88 memset(mbox->queue, 0, sizeof(mbox->queue));
emilmont 1:a7366e261ca3 89 mbox->def.pool = mbox->queue;
emilmont 1:a7366e261ca3 90 mbox->def.queue_sz = queue_sz;
emilmont 1:a7366e261ca3 91 #endif
emilmont 1:a7366e261ca3 92 mbox->id = osMessageCreate(&mbox->def, NULL);
emilmont 1:a7366e261ca3 93 return (mbox->id == NULL) ? (ERR_MEM) : (ERR_OK);
emilmont 1:a7366e261ca3 94 }
emilmont 1:a7366e261ca3 95
emilmont 1:a7366e261ca3 96 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 97 * Routine: sys_mbox_free
emilmont 1:a7366e261ca3 98 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 99 * Description:
emilmont 1:a7366e261ca3 100 * Deallocates a mailbox. If there are messages still present in the
emilmont 1:a7366e261ca3 101 * mailbox when the mailbox is deallocated, it is an indication of a
emilmont 1:a7366e261ca3 102 * programming error in lwIP and the developer should be notified.
emilmont 1:a7366e261ca3 103 * Inputs:
emilmont 1:a7366e261ca3 104 * sys_mbox_t *mbox -- Handle of mailbox
emilmont 1:a7366e261ca3 105 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 106 void sys_mbox_free(sys_mbox_t *mbox) {
emilmont 1:a7366e261ca3 107 osEvent event = osMessageGet(mbox->id, 0);
emilmont 1:a7366e261ca3 108 if (event.status == osEventMessage)
emilmont 1:a7366e261ca3 109 error("sys_mbox_free error\n");
emilmont 1:a7366e261ca3 110 }
emilmont 1:a7366e261ca3 111
emilmont 1:a7366e261ca3 112 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 113 * Routine: sys_mbox_post
emilmont 1:a7366e261ca3 114 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 115 * Description:
emilmont 1:a7366e261ca3 116 * Post the "msg" to the mailbox.
emilmont 1:a7366e261ca3 117 * Inputs:
emilmont 1:a7366e261ca3 118 * sys_mbox_t mbox -- Handle of mailbox
emilmont 1:a7366e261ca3 119 * void *msg -- Pointer to data to post
emilmont 1:a7366e261ca3 120 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 121 void sys_mbox_post(sys_mbox_t *mbox, void *msg) {
emilmont 1:a7366e261ca3 122 if (osMessagePut(mbox->id, (uint32_t)msg, osWaitForever) != osOK)
emilmont 1:a7366e261ca3 123 error("sys_mbox_post error\n");
emilmont 1:a7366e261ca3 124 }
emilmont 1:a7366e261ca3 125
emilmont 1:a7366e261ca3 126 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 127 * Routine: sys_mbox_trypost
emilmont 1:a7366e261ca3 128 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 129 * Description:
emilmont 1:a7366e261ca3 130 * Try to post the "msg" to the mailbox. Returns immediately with
emilmont 1:a7366e261ca3 131 * error if cannot.
emilmont 1:a7366e261ca3 132 * Inputs:
emilmont 1:a7366e261ca3 133 * sys_mbox_t mbox -- Handle of mailbox
emilmont 1:a7366e261ca3 134 * void *msg -- Pointer to data to post
emilmont 1:a7366e261ca3 135 * Outputs:
emilmont 1:a7366e261ca3 136 * err_t -- ERR_OK if message posted, else ERR_MEM
emilmont 1:a7366e261ca3 137 * if not.
emilmont 1:a7366e261ca3 138 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 139 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) {
emilmont 1:a7366e261ca3 140 osStatus status = osMessagePut(mbox->id, (uint32_t)msg, 0);
emilmont 1:a7366e261ca3 141 return (status == osOK) ? (ERR_OK) : (ERR_MEM);
emilmont 1:a7366e261ca3 142 }
emilmont 1:a7366e261ca3 143
emilmont 1:a7366e261ca3 144 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 145 * Routine: sys_arch_mbox_fetch
emilmont 1:a7366e261ca3 146 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 147 * Description:
emilmont 1:a7366e261ca3 148 * Blocks the thread until a message arrives in the mailbox, but does
emilmont 1:a7366e261ca3 149 * not block the thread longer than "timeout" milliseconds (similar to
emilmont 1:a7366e261ca3 150 * the sys_arch_sem_wait() function). The "msg" argument is a result
emilmont 1:a7366e261ca3 151 * parameter that is set by the function (i.e., by doing "*msg =
emilmont 1:a7366e261ca3 152 * ptr"). The "msg" parameter maybe NULL to indicate that the message
emilmont 1:a7366e261ca3 153 * should be dropped.
emilmont 1:a7366e261ca3 154 *
emilmont 1:a7366e261ca3 155 * The return values are the same as for the sys_arch_sem_wait() function:
emilmont 1:a7366e261ca3 156 * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
emilmont 1:a7366e261ca3 157 * timeout.
emilmont 1:a7366e261ca3 158 *
emilmont 1:a7366e261ca3 159 * Note that a function with a similar name, sys_mbox_fetch(), is
emilmont 1:a7366e261ca3 160 * implemented by lwIP.
emilmont 1:a7366e261ca3 161 * Inputs:
emilmont 1:a7366e261ca3 162 * sys_mbox_t mbox -- Handle of mailbox
emilmont 1:a7366e261ca3 163 * void **msg -- Pointer to pointer to msg received
emilmont 1:a7366e261ca3 164 * u32_t timeout -- Number of milliseconds until timeout
emilmont 1:a7366e261ca3 165 * Outputs:
emilmont 1:a7366e261ca3 166 * u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
emilmont 1:a7366e261ca3 167 * of milliseconds until received.
emilmont 1:a7366e261ca3 168 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 169 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) {
emilmont 1:a7366e261ca3 170 u32_t start = us_ticker_read();
emilmont 1:a7366e261ca3 171
emilmont 1:a7366e261ca3 172 osEvent event = osMessageGet(mbox->id, (timeout != 0)?(timeout):(osWaitForever));
emilmont 1:a7366e261ca3 173 if (event.status != osEventMessage)
emilmont 1:a7366e261ca3 174 return SYS_ARCH_TIMEOUT;
emilmont 1:a7366e261ca3 175
emilmont 1:a7366e261ca3 176 *msg = (void *)event.value.v;
emilmont 1:a7366e261ca3 177
emilmont 1:a7366e261ca3 178 return (us_ticker_read() - start) / 1000;
emilmont 1:a7366e261ca3 179 }
emilmont 1:a7366e261ca3 180
emilmont 1:a7366e261ca3 181 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 182 * Routine: sys_arch_mbox_tryfetch
emilmont 1:a7366e261ca3 183 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 184 * Description:
emilmont 1:a7366e261ca3 185 * Similar to sys_arch_mbox_fetch, but if message is not ready
emilmont 1:a7366e261ca3 186 * immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is
emilmont 1:a7366e261ca3 187 * returned.
emilmont 1:a7366e261ca3 188 * Inputs:
emilmont 1:a7366e261ca3 189 * sys_mbox_t mbox -- Handle of mailbox
emilmont 1:a7366e261ca3 190 * void **msg -- Pointer to pointer to msg received
emilmont 1:a7366e261ca3 191 * Outputs:
emilmont 1:a7366e261ca3 192 * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
emilmont 1:a7366e261ca3 193 * return ERR_OK.
emilmont 1:a7366e261ca3 194 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 195 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) {
emilmont 1:a7366e261ca3 196 osEvent event = osMessageGet(mbox->id, 0);
emilmont 1:a7366e261ca3 197 if (event.status != osEventMessage)
emilmont 1:a7366e261ca3 198 return SYS_MBOX_EMPTY;
emilmont 1:a7366e261ca3 199
emilmont 1:a7366e261ca3 200 *msg = (void *)event.value.v;
emilmont 1:a7366e261ca3 201
emilmont 1:a7366e261ca3 202 return ERR_OK;
emilmont 1:a7366e261ca3 203 }
emilmont 1:a7366e261ca3 204
emilmont 1:a7366e261ca3 205 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 206 * Routine: sys_sem_new
emilmont 1:a7366e261ca3 207 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 208 * Description:
emilmont 1:a7366e261ca3 209 * Creates and returns a new semaphore. The "ucCount" argument specifies
emilmont 1:a7366e261ca3 210 * the initial state of the semaphore.
emilmont 1:a7366e261ca3 211 * NOTE: Currently this routine only creates counts of 1 or 0
emilmont 1:a7366e261ca3 212 * Inputs:
emilmont 1:a7366e261ca3 213 * sys_sem_t sem -- Handle of semaphore
emilmont 1:a7366e261ca3 214 * u8_t count -- Initial count of semaphore
emilmont 1:a7366e261ca3 215 * Outputs:
emilmont 1:a7366e261ca3 216 * err_t -- ERR_OK if semaphore created
emilmont 1:a7366e261ca3 217 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 218 err_t sys_sem_new(sys_sem_t *sem, u8_t count) {
emilmont 1:a7366e261ca3 219 #ifdef CMSIS_OS_RTX
emilmont 1:a7366e261ca3 220 memset(sem->data, 0, sizeof(uint32_t)*2);
emilmont 1:a7366e261ca3 221 sem->def.semaphore = sem->data;
emilmont 1:a7366e261ca3 222 #endif
emilmont 1:a7366e261ca3 223 // We cannot initialize the semaphore to 0
emilmont 1:a7366e261ca3 224 sem->id = osSemaphoreCreate(&sem->def, (count ? count : 1));
emilmont 1:a7366e261ca3 225 if (sem->id == NULL)
emilmont 1:a7366e261ca3 226 error("sys_sem_new create error\n");
emilmont 1:a7366e261ca3 227
emilmont 1:a7366e261ca3 228 // We cannot initialize the semaphore to 0
emilmont 1:a7366e261ca3 229 if (count == 0) {
emilmont 1:a7366e261ca3 230 if (osSemaphoreWait(sem->id, osWaitForever) < 1)
emilmont 1:a7366e261ca3 231 error("sys_sem_new wait error\n");
emilmont 1:a7366e261ca3 232 }
emilmont 1:a7366e261ca3 233
emilmont 1:a7366e261ca3 234 return ERR_OK;
emilmont 1:a7366e261ca3 235 }
emilmont 1:a7366e261ca3 236
emilmont 1:a7366e261ca3 237 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 238 * Routine: sys_arch_sem_wait
emilmont 1:a7366e261ca3 239 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 240 * Description:
emilmont 1:a7366e261ca3 241 * Blocks the thread while waiting for the semaphore to be
emilmont 1:a7366e261ca3 242 * signaled. If the "timeout" argument is non-zero, the thread should
emilmont 1:a7366e261ca3 243 * only be blocked for the specified time (measured in
emilmont 1:a7366e261ca3 244 * milliseconds).
emilmont 1:a7366e261ca3 245 *
emilmont 1:a7366e261ca3 246 * If the timeout argument is non-zero, the return value is the number of
emilmont 1:a7366e261ca3 247 * milliseconds spent waiting for the semaphore to be signaled. If the
emilmont 1:a7366e261ca3 248 * semaphore wasn't signaled within the specified time, the return value is
emilmont 1:a7366e261ca3 249 * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
emilmont 1:a7366e261ca3 250 * (i.e., it was already signaled), the function may return zero.
emilmont 1:a7366e261ca3 251 *
emilmont 1:a7366e261ca3 252 * Notice that lwIP implements a function with a similar name,
emilmont 1:a7366e261ca3 253 * sys_sem_wait(), that uses the sys_arch_sem_wait() function.
emilmont 1:a7366e261ca3 254 * Inputs:
emilmont 1:a7366e261ca3 255 * sys_sem_t sem -- Semaphore to wait on
emilmont 1:a7366e261ca3 256 * u32_t timeout -- Number of milliseconds until timeout
emilmont 1:a7366e261ca3 257 * Outputs:
emilmont 1:a7366e261ca3 258 * u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
emilmont 1:a7366e261ca3 259 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 260 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) {
emilmont 1:a7366e261ca3 261 u32_t start = us_ticker_read();
emilmont 1:a7366e261ca3 262
emilmont 1:a7366e261ca3 263 if (osSemaphoreWait(sem->id, (timeout != 0)?(timeout):(osWaitForever)) < 1)
emilmont 1:a7366e261ca3 264 return SYS_ARCH_TIMEOUT;
emilmont 1:a7366e261ca3 265
emilmont 1:a7366e261ca3 266 return (us_ticker_read() - start) / 1000;
emilmont 1:a7366e261ca3 267 }
emilmont 1:a7366e261ca3 268
emilmont 1:a7366e261ca3 269 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 270 * Routine: sys_sem_signal
emilmont 1:a7366e261ca3 271 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 272 * Description:
emilmont 1:a7366e261ca3 273 * Signals (releases) a semaphore
emilmont 1:a7366e261ca3 274 * Inputs:
emilmont 1:a7366e261ca3 275 * sys_sem_t sem -- Semaphore to signal
emilmont 1:a7366e261ca3 276 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 277 void sys_sem_signal(sys_sem_t *data) {
emilmont 1:a7366e261ca3 278 if (osSemaphoreRelease(data->id) != osOK)
emilmont 1:a7366e261ca3 279 mbed_die(); /* Can be called by ISR do not use printf */
emilmont 1:a7366e261ca3 280 }
emilmont 1:a7366e261ca3 281
emilmont 1:a7366e261ca3 282 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 283 * Routine: sys_sem_free
emilmont 1:a7366e261ca3 284 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 285 * Description:
emilmont 1:a7366e261ca3 286 * Deallocates a semaphore
emilmont 1:a7366e261ca3 287 * Inputs:
emilmont 1:a7366e261ca3 288 * sys_sem_t sem -- Semaphore to free
emilmont 1:a7366e261ca3 289 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 290 void sys_sem_free(sys_sem_t *sem) {}
emilmont 1:a7366e261ca3 291
emilmont 1:a7366e261ca3 292 /** Create a new mutex
emilmont 1:a7366e261ca3 293 * @param mutex pointer to the mutex to create
emilmont 1:a7366e261ca3 294 * @return a new mutex */
emilmont 1:a7366e261ca3 295 err_t sys_mutex_new(sys_mutex_t *mutex) {
emilmont 1:a7366e261ca3 296 #ifdef CMSIS_OS_RTX
emilmont 1:a7366e261ca3 297 memset(mutex->data, 0, sizeof(int32_t)*3);
emilmont 1:a7366e261ca3 298 mutex->def.mutex = mutex->data;
emilmont 1:a7366e261ca3 299 #endif
emilmont 1:a7366e261ca3 300 mutex->id = osMutexCreate(&mutex->def);
emilmont 1:a7366e261ca3 301 if (mutex->id == NULL)
emilmont 1:a7366e261ca3 302 return ERR_MEM;
emilmont 1:a7366e261ca3 303
emilmont 1:a7366e261ca3 304 return ERR_OK;
emilmont 1:a7366e261ca3 305 }
emilmont 1:a7366e261ca3 306
emilmont 1:a7366e261ca3 307 /** Lock a mutex
emilmont 1:a7366e261ca3 308 * @param mutex the mutex to lock */
emilmont 1:a7366e261ca3 309 void sys_mutex_lock(sys_mutex_t *mutex) {
emilmont 1:a7366e261ca3 310 if (osMutexWait(mutex->id, osWaitForever) != osOK)
emilmont 1:a7366e261ca3 311 error("sys_mutex_lock error\n");
emilmont 1:a7366e261ca3 312 }
emilmont 1:a7366e261ca3 313
emilmont 1:a7366e261ca3 314 /** Unlock a mutex
emilmont 1:a7366e261ca3 315 * @param mutex the mutex to unlock */
emilmont 1:a7366e261ca3 316 void sys_mutex_unlock(sys_mutex_t *mutex) {
emilmont 1:a7366e261ca3 317 if (osMutexRelease(mutex->id) != osOK)
emilmont 1:a7366e261ca3 318 error("sys_mutex_unlock error\n");
emilmont 1:a7366e261ca3 319 }
emilmont 1:a7366e261ca3 320
emilmont 1:a7366e261ca3 321 /** Delete a mutex
emilmont 1:a7366e261ca3 322 * @param mutex the mutex to delete */
emilmont 1:a7366e261ca3 323 void sys_mutex_free(sys_mutex_t *mutex) {}
emilmont 1:a7366e261ca3 324
emilmont 1:a7366e261ca3 325 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 326 * Routine: sys_init
emilmont 1:a7366e261ca3 327 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 328 * Description:
emilmont 1:a7366e261ca3 329 * Initialize sys arch
emilmont 1:a7366e261ca3 330 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 331 osMutexId lwip_sys_mutex;
emilmont 1:a7366e261ca3 332 osMutexDef(lwip_sys_mutex);
emilmont 1:a7366e261ca3 333
emilmont 1:a7366e261ca3 334 void sys_init(void) {
emilmont 1:a7366e261ca3 335 lwip_sys_mutex = osMutexCreate(osMutex(lwip_sys_mutex));
emilmont 1:a7366e261ca3 336 if (lwip_sys_mutex == NULL)
emilmont 1:a7366e261ca3 337 error("sys_init error\n");
emilmont 1:a7366e261ca3 338 }
emilmont 1:a7366e261ca3 339
emilmont 1:a7366e261ca3 340 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 341 * Routine: sys_arch_protect
emilmont 1:a7366e261ca3 342 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 343 * Description:
emilmont 1:a7366e261ca3 344 * This optional function does a "fast" critical region protection and
emilmont 1:a7366e261ca3 345 * returns the previous protection level. This function is only called
emilmont 1:a7366e261ca3 346 * during very short critical regions. An embedded system which supports
emilmont 1:a7366e261ca3 347 * ISR-based drivers might want to implement this function by disabling
emilmont 1:a7366e261ca3 348 * interrupts. Task-based systems might want to implement this by using
emilmont 1:a7366e261ca3 349 * a mutex or disabling tasking. This function should support recursive
emilmont 1:a7366e261ca3 350 * calls from the same task or interrupt. In other words,
emilmont 1:a7366e261ca3 351 * sys_arch_protect() could be called while already protected. In
emilmont 1:a7366e261ca3 352 * that case the return value indicates that it is already protected.
emilmont 1:a7366e261ca3 353 *
emilmont 1:a7366e261ca3 354 * sys_arch_protect() is only required if your port is supporting an
emilmont 1:a7366e261ca3 355 * operating system.
emilmont 1:a7366e261ca3 356 * Outputs:
emilmont 1:a7366e261ca3 357 * sys_prot_t -- Previous protection level (not used here)
emilmont 1:a7366e261ca3 358 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 359 sys_prot_t sys_arch_protect(void) {
emilmont 1:a7366e261ca3 360 if (osMutexWait(lwip_sys_mutex, osWaitForever) != osOK)
emilmont 1:a7366e261ca3 361 error("sys_arch_protect error\n");
emilmont 1:a7366e261ca3 362 return (sys_prot_t) 1;
emilmont 1:a7366e261ca3 363 }
emilmont 1:a7366e261ca3 364
emilmont 1:a7366e261ca3 365 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 366 * Routine: sys_arch_unprotect
emilmont 1:a7366e261ca3 367 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 368 * Description:
emilmont 1:a7366e261ca3 369 * This optional function does a "fast" set of critical region
emilmont 1:a7366e261ca3 370 * protection to the value specified by pval. See the documentation for
emilmont 1:a7366e261ca3 371 * sys_arch_protect() for more information. This function is only
emilmont 1:a7366e261ca3 372 * required if your port is supporting an operating system.
emilmont 1:a7366e261ca3 373 * Inputs:
emilmont 1:a7366e261ca3 374 * sys_prot_t -- Previous protection level (not used here)
emilmont 1:a7366e261ca3 375 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 376 void sys_arch_unprotect(sys_prot_t p) {
emilmont 1:a7366e261ca3 377 if (osMutexRelease(lwip_sys_mutex) != osOK)
emilmont 1:a7366e261ca3 378 error("sys_arch_unprotect error\n");
emilmont 1:a7366e261ca3 379 }
emilmont 1:a7366e261ca3 380
emilmont 1:a7366e261ca3 381 u32_t sys_now(void) {
emilmont 1:a7366e261ca3 382 return us_ticker_read() / 1000;
emilmont 1:a7366e261ca3 383 }
emilmont 1:a7366e261ca3 384
emilmont 1:a7366e261ca3 385 void sys_msleep(u32_t ms) {
emilmont 1:a7366e261ca3 386 osDelay(ms);
emilmont 1:a7366e261ca3 387 }
emilmont 1:a7366e261ca3 388
emilmont 1:a7366e261ca3 389 // Keep a pool of thread structures
emilmont 1:a7366e261ca3 390 static int thread_pool_index = 0;
emilmont 1:a7366e261ca3 391 static sys_thread_data_t thread_pool[SYS_THREAD_POOL_N];
emilmont 1:a7366e261ca3 392
emilmont 1:a7366e261ca3 393 /*---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 394 * Routine: sys_thread_new
emilmont 1:a7366e261ca3 395 *---------------------------------------------------------------------------*
emilmont 1:a7366e261ca3 396 * Description:
emilmont 1:a7366e261ca3 397 * Starts a new thread with priority "prio" that will begin its
emilmont 1:a7366e261ca3 398 * execution in the function "thread()". The "arg" argument will be
emilmont 1:a7366e261ca3 399 * passed as an argument to the thread() function. The id of the new
emilmont 1:a7366e261ca3 400 * thread is returned. Both the id and the priority are system
emilmont 1:a7366e261ca3 401 * dependent.
emilmont 1:a7366e261ca3 402 * Inputs:
emilmont 1:a7366e261ca3 403 * char *name -- Name of thread
emilmont 1:a7366e261ca3 404 * void (*thread)(void *arg) -- Pointer to function to run.
emilmont 1:a7366e261ca3 405 * void *arg -- Argument passed into function
emilmont 1:a7366e261ca3 406 * int stacksize -- Required stack amount in bytes
emilmont 1:a7366e261ca3 407 * int priority -- Thread priority
emilmont 1:a7366e261ca3 408 * Outputs:
emilmont 1:a7366e261ca3 409 * sys_thread_t -- Pointer to thread handle.
emilmont 1:a7366e261ca3 410 *---------------------------------------------------------------------------*/
emilmont 1:a7366e261ca3 411 sys_thread_t sys_thread_new(const char *pcName,
emilmont 1:a7366e261ca3 412 void (*thread)(void *arg),
emilmont 1:a7366e261ca3 413 void *arg, int stacksize, int priority) {
emilmont 1:a7366e261ca3 414 LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName));
emilmont 1:a7366e261ca3 415
emilmont 1:a7366e261ca3 416 if (thread_pool_index >= SYS_THREAD_POOL_N)
emilmont 1:a7366e261ca3 417 error("sys_thread_new number error\n");
emilmont 1:a7366e261ca3 418 sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index];
emilmont 1:a7366e261ca3 419 thread_pool_index++;
emilmont 1:a7366e261ca3 420
emilmont 1:a7366e261ca3 421 #ifdef CMSIS_OS_RTX
emilmont 1:a7366e261ca3 422 t->def.pthread = (os_pthread)thread;
emilmont 1:a7366e261ca3 423 t->def.tpriority = (osPriority)priority;
emilmont 1:a7366e261ca3 424 t->def.instances = 1;
emilmont 1:a7366e261ca3 425 t->def.stacksize = stacksize;
emilmont 1:a7366e261ca3 426 #endif
emilmont 1:a7366e261ca3 427 t->id = osThreadCreate(&t->def, arg);
emilmont 1:a7366e261ca3 428 if (t->id == NULL)
emilmont 1:a7366e261ca3 429 error("sys_thread_new create error\n");
emilmont 1:a7366e261ca3 430
emilmont 1:a7366e261ca3 431 return t;
emilmont 1:a7366e261ca3 432 }
emilmont 1:a7366e261ca3 433
emilmont 1:a7366e261ca3 434 #endif
emilmont 1:a7366e261ca3 435
emilmont 1:a7366e261ca3 436 #ifdef LWIP_DEBUG
emilmont 1:a7366e261ca3 437
emilmont 1:a7366e261ca3 438 /** \brief Displays an error message on assertion
emilmont 1:a7366e261ca3 439
emilmont 1:a7366e261ca3 440 This function will display an error message on an assertion
emilmont 1:a7366e261ca3 441 to the debug output.
emilmont 1:a7366e261ca3 442
emilmont 1:a7366e261ca3 443 \param[in] msg Error message to display
emilmont 1:a7366e261ca3 444 \param[in] line Line number in file with error
emilmont 1:a7366e261ca3 445 \param[in] file Filename with error
emilmont 1:a7366e261ca3 446 */
emilmont 1:a7366e261ca3 447 void assert_printf(char *msg, int line, char *file) {
emilmont 1:a7366e261ca3 448 if (msg)
emilmont 1:a7366e261ca3 449 error("%s:%d in file %s\n", msg, line, file);
emilmont 1:a7366e261ca3 450 else
emilmont 1:a7366e261ca3 451 error("LWIP ASSERT\n");
emilmont 1:a7366e261ca3 452 }
emilmont 1:a7366e261ca3 453
emilmont 1:a7366e261ca3 454 #endif /* LWIP_DEBUG */