local fork (temporary)

Dependents:   VodafoneUSBModem_bleedingedge2

Fork of lwip-sys by mbed official

Committer:
ashleymills
Date:
Fri Apr 26 16:53:18 2013 +0000
Revision:
9:6ba677cca4d8
Parent:
7:b409691fb352
Minor change for resolution of error.h

Who changed what in which revision?

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