Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lwip_sys_arch.c
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 #include <string.h> 00019 00020 /* mbed includes */ 00021 #include "mbed_error.h" 00022 #include "mbed_interface.h" 00023 #include "mbed_rtos_storage.h" 00024 00025 /* lwIP includes. */ 00026 #include "lwip/opt.h" 00027 #include "lwip/debug.h" 00028 #include "lwip/def.h" 00029 #include "lwip/sys.h" 00030 #include "lwip/mem.h" 00031 00032 /* Define the heap ourselves to give us section placement control */ 00033 #ifndef ETHMEM_SECTION 00034 #if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) 00035 # if defined (__ICCARM__) 00036 # define ETHMEM_SECTION 00037 # elif defined(TOOLCHAIN_GCC_CR) 00038 # define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32"))) 00039 # else 00040 # define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned)) 00041 # endif 00042 #elif defined(TARGET_LPC1768) 00043 # if defined (__ICCARM__) 00044 # define ETHMEM_SECTION 00045 # elif defined(TOOLCHAIN_GCC_CR) 00046 # define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32"))) 00047 # else 00048 # define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned)) 00049 # endif 00050 #else 00051 #define ETHMEM_SECTION 00052 #endif 00053 #endif 00054 00055 /* LWIP's mem.c doesn't give visibility of its overhead; memory area has to be big 00056 * enough to hold "MEM_SIZE" (which we specify) plus mem.c's overhead. Have to work 00057 * it all out here, copying code from mem.c */ 00058 struct mem { 00059 /** index (-> ram[next]) of the next struct */ 00060 mem_size_t next; 00061 /** index (-> ram[prev]) of the previous struct */ 00062 mem_size_t prev; 00063 /** 1: this area is used; 0: this area is unused */ 00064 u8_t used; 00065 }; 00066 00067 #define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) 00068 #define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) 00069 00070 #if defined (__ICCARM__) 00071 #pragma location = ".ethusbram" 00072 #endif 00073 LWIP_DECLARE_MEMORY_ALIGNED(lwip_ram_heap, MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM)) ETHMEM_SECTION; 00074 00075 #if NO_SYS==1 00076 #include "cmsis.h" 00077 00078 /* Saved total time in ms since timer was enabled */ 00079 static volatile u32_t systick_timems; 00080 00081 /* Enable systick rate and interrupt */ 00082 void SysTick_Init(void) { 00083 if (SysTick_Config(SystemCoreClock / 1000)) { 00084 while (1); /* Capture error */ 00085 } 00086 } 00087 00088 /** \brief SysTick IRQ handler and timebase management 00089 * 00090 * This function keeps a timebase for the sysTick that can be 00091 * used for other functions. It also calls an external function 00092 * (SysTick_User) that must be defined outside this handler. 00093 */ 00094 void SysTick_Handler(void) { 00095 systick_timems++; 00096 } 00097 00098 /* Delay for the specified number of milliSeconds */ 00099 void osDelay(uint32_t ms) { 00100 uint32_t to = ms + systick_timems; 00101 while (to > systick_timems); 00102 } 00103 00104 /* Returns the current time in mS. This is needed for the LWIP timers */ 00105 u32_t sys_now(void) { 00106 return (u32_t) systick_timems; 00107 } 00108 00109 #else 00110 /* CMSIS-RTOS implementation of the lwip operating system abstraction */ 00111 #include "arch/sys_arch.h" 00112 00113 /*---------------------------------------------------------------------------* 00114 * Routine: sys_mbox_new 00115 *---------------------------------------------------------------------------* 00116 * Description: 00117 * Creates a new mailbox 00118 * Inputs: 00119 * sys_mbox_t mbox -- Handle of mailbox 00120 * int queue_sz -- Size of elements in the mailbox 00121 * Outputs: 00122 * err_t -- ERR_OK if message posted, else ERR_MEM 00123 *---------------------------------------------------------------------------*/ 00124 err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { 00125 if (queue_sz > MB_SIZE) 00126 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_INVALID_SIZE), "sys_mbox_new size error\n", queue_sz); 00127 00128 memset(mbox, 0, sizeof(*mbox)); 00129 00130 mbox->attr.cb_mem = &mbox->data; 00131 mbox->attr.cb_size = sizeof(mbox->data); 00132 mbox->id = osEventFlagsNew(&mbox->attr); 00133 if (mbox->id == NULL) 00134 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_mbox_new create error\n", (u32_t)mbox); 00135 00136 osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); 00137 00138 return ERR_OK; 00139 } 00140 00141 /*---------------------------------------------------------------------------* 00142 * Routine: sys_mbox_free 00143 *---------------------------------------------------------------------------* 00144 * Description: 00145 * Deallocates a mailbox. If there are messages still present in the 00146 * mailbox when the mailbox is deallocated, it is an indication of a 00147 * programming error in lwIP and the developer should be notified. 00148 * Inputs: 00149 * sys_mbox_t *mbox -- Handle of mailbox 00150 *---------------------------------------------------------------------------*/ 00151 void sys_mbox_free(sys_mbox_t *mbox) { 00152 if (mbox->post_idx != mbox->fetch_idx) 00153 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_INVALID_INDEX), "sys_mbox_free error\n", (u32_t)mbox->fetch_idx); 00154 } 00155 00156 /*---------------------------------------------------------------------------* 00157 * Routine: sys_mbox_post 00158 *---------------------------------------------------------------------------* 00159 * Description: 00160 * Post the "msg" to the mailbox. 00161 * Inputs: 00162 * sys_mbox_t mbox -- Handle of mailbox 00163 * void *msg -- Pointer to data to post 00164 *---------------------------------------------------------------------------*/ 00165 void sys_mbox_post(sys_mbox_t *mbox, void *msg) { 00166 osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT, 00167 osFlagsWaitAny | osFlagsNoClear, osWaitForever); 00168 00169 int state = osKernelLock(); 00170 00171 mbox->queue[mbox->post_idx % MB_SIZE] = msg; 00172 mbox->post_idx += 1; 00173 00174 osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT); 00175 if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1) 00176 osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT); 00177 00178 osKernelRestoreLock(state); 00179 } 00180 00181 /*---------------------------------------------------------------------------* 00182 * Routine: sys_mbox_trypost 00183 *---------------------------------------------------------------------------* 00184 * Description: 00185 * Try to post the "msg" to the mailbox. Returns immediately with 00186 * error if cannot. 00187 * Inputs: 00188 * sys_mbox_t mbox -- Handle of mailbox 00189 * void *msg -- Pointer to data to post 00190 * Outputs: 00191 * err_t -- ERR_OK if message posted, else ERR_MEM 00192 * if not. 00193 *---------------------------------------------------------------------------*/ 00194 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { 00195 uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT, 00196 osFlagsWaitAny | osFlagsNoClear, 0); 00197 if ((flags & osFlagsError) || !(flags & SYS_MBOX_POST_EVENT)) { 00198 MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_mbox_trypost error\n", flags); 00199 return ERR_MEM; 00200 } 00201 00202 int state = osKernelLock(); 00203 00204 mbox->queue[mbox->post_idx % MB_SIZE] = msg; 00205 mbox->post_idx += 1; 00206 00207 osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT); 00208 if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1) 00209 osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT); 00210 00211 osKernelRestoreLock(state); 00212 return ERR_OK; 00213 } 00214 00215 /*---------------------------------------------------------------------------* 00216 * Routine: sys_arch_mbox_fetch 00217 *---------------------------------------------------------------------------* 00218 * Description: 00219 * Blocks the thread until a message arrives in the mailbox, but does 00220 * not block the thread longer than "timeout" milliseconds (similar to 00221 * the sys_arch_sem_wait() function). The "msg" argument is a result 00222 * parameter that is set by the function (i.e., by doing "*msg = 00223 * ptr"). The "msg" parameter maybe NULL to indicate that the message 00224 * should be dropped. 00225 * 00226 * The return values are the same as for the sys_arch_sem_wait() function: 00227 * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a 00228 * timeout. 00229 * 00230 * Note that a function with a similar name, sys_mbox_fetch(), is 00231 * implemented by lwIP. 00232 * Inputs: 00233 * sys_mbox_t mbox -- Handle of mailbox 00234 * void **msg -- Pointer to pointer to msg received 00235 * u32_t timeout -- Number of milliseconds until timeout 00236 * Outputs: 00237 * u32_t -- SYS_ARCH_TIMEOUT if timeout, else number 00238 * of milliseconds until received. 00239 *---------------------------------------------------------------------------*/ 00240 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { 00241 uint32_t start = osKernelGetTickCount(); 00242 uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, 00243 osFlagsWaitAny | osFlagsNoClear, (timeout ? timeout : osWaitForever)); 00244 if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) { 00245 MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_TIME_OUT), "sys_arch_mbox_fetch time-out\n", flags); 00246 return SYS_ARCH_TIMEOUT; 00247 } 00248 00249 int state = osKernelLock(); 00250 00251 if (msg) 00252 *msg = mbox->queue[mbox->fetch_idx % MB_SIZE]; 00253 mbox->fetch_idx += 1; 00254 00255 osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); 00256 if (mbox->post_idx == mbox->fetch_idx) 00257 osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT); 00258 00259 osKernelRestoreLock(state); 00260 return osKernelGetTickCount() - start; 00261 } 00262 00263 /*---------------------------------------------------------------------------* 00264 * Routine: sys_arch_mbox_tryfetch 00265 *---------------------------------------------------------------------------* 00266 * Description: 00267 * Similar to sys_arch_mbox_fetch, but if message is not ready 00268 * immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is 00269 * returned. 00270 * Inputs: 00271 * sys_mbox_t mbox -- Handle of mailbox 00272 * void **msg -- Pointer to pointer to msg received 00273 * Outputs: 00274 * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise, 00275 * return ERR_OK. 00276 *---------------------------------------------------------------------------*/ 00277 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { 00278 uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, 00279 osFlagsWaitAny | osFlagsNoClear, 0); 00280 if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) { 00281 MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_arch_mbox_tryfetch empty\n", flags); 00282 return SYS_MBOX_EMPTY; 00283 } 00284 00285 int state = osKernelLock(); 00286 00287 if (msg) 00288 *msg = mbox->queue[mbox->fetch_idx % MB_SIZE]; 00289 mbox->fetch_idx += 1; 00290 00291 osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); 00292 if (mbox->post_idx == mbox->fetch_idx) 00293 osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT); 00294 00295 osKernelRestoreLock(state); 00296 return ERR_OK; 00297 } 00298 00299 /*---------------------------------------------------------------------------* 00300 * Routine: sys_sem_new 00301 *---------------------------------------------------------------------------* 00302 * Description: 00303 * Creates and returns a new semaphore. The "ucCount" argument specifies 00304 * the initial state of the semaphore. 00305 * NOTE: Currently this routine only creates counts of 1 or 0 00306 * Inputs: 00307 * sys_sem_t sem -- Handle of semaphore 00308 * u8_t count -- Initial count of semaphore 00309 * Outputs: 00310 * err_t -- ERR_OK if semaphore created 00311 *---------------------------------------------------------------------------*/ 00312 err_t sys_sem_new(sys_sem_t *sem, u8_t count) { 00313 memset(sem, 0, sizeof(*sem)); 00314 sem->attr.cb_mem = &sem->data; 00315 sem->attr.cb_size = sizeof(sem->data); 00316 sem->id = osSemaphoreNew(UINT16_MAX, count, &sem->attr); 00317 if (sem->id == NULL) 00318 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_sem_new create error\n", (u32_t)sem); 00319 00320 return ERR_OK; 00321 } 00322 00323 /*---------------------------------------------------------------------------* 00324 * Routine: sys_arch_sem_wait 00325 *---------------------------------------------------------------------------* 00326 * Description: 00327 * Blocks the thread while waiting for the semaphore to be 00328 * signaled. If the "timeout" argument is non-zero, the thread should 00329 * only be blocked for the specified time (measured in 00330 * milliseconds). 00331 * 00332 * If the timeout argument is non-zero, the return value is the number of 00333 * milliseconds spent waiting for the semaphore to be signaled. If the 00334 * semaphore wasn't signaled within the specified time, the return value is 00335 * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore 00336 * (i.e., it was already signaled), the function may return zero. 00337 * 00338 * Notice that lwIP implements a function with a similar name, 00339 * sys_sem_wait(), that uses the sys_arch_sem_wait() function. 00340 * Inputs: 00341 * sys_sem_t sem -- Semaphore to wait on 00342 * u32_t timeout -- Number of milliseconds until timeout 00343 * Outputs: 00344 * u32_t -- Time elapsed or SYS_ARCH_TIMEOUT. 00345 *---------------------------------------------------------------------------*/ 00346 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { 00347 u32_t start = osKernelGetTickCount(); 00348 00349 if (osSemaphoreAcquire(sem->id, (timeout != 0)?(timeout):(osWaitForever)) != osOK) { 00350 MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_TIME_OUT), "sys_arch_sem_wait time out\n", (u32_t)sem); 00351 return SYS_ARCH_TIMEOUT; 00352 } 00353 00354 return osKernelGetTickCount() - start; 00355 } 00356 00357 /*---------------------------------------------------------------------------* 00358 * Routine: sys_sem_signal 00359 *---------------------------------------------------------------------------* 00360 * Description: 00361 * Signals (releases) a semaphore 00362 * Inputs: 00363 * sys_sem_t sem -- Semaphore to signal 00364 *---------------------------------------------------------------------------*/ 00365 void sys_sem_signal(sys_sem_t *data) { 00366 if (osSemaphoreRelease(data->id) != osOK) 00367 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_SEMAPHORE_UNLOCK_FAILED), "sys_sem_signal error\n", (u32_t)data->id); 00368 } 00369 00370 /*---------------------------------------------------------------------------* 00371 * Routine: sys_sem_free 00372 *---------------------------------------------------------------------------* 00373 * Description: 00374 * Deallocates a semaphore 00375 * Inputs: 00376 * sys_sem_t sem -- Semaphore to free 00377 *---------------------------------------------------------------------------*/ 00378 void sys_sem_free(sys_sem_t *sem) {} 00379 00380 /** Create a new mutex 00381 * @param mutex pointer to the mutex to create 00382 * @return a new mutex */ 00383 err_t sys_mutex_new(sys_mutex_t *mutex) { 00384 memset(mutex, 0, sizeof(*mutex)); 00385 mutex->attr.name = "lwip_mutex"; 00386 mutex->attr.cb_mem = &mutex->data; 00387 mutex->attr.cb_size = sizeof(mutex->data); 00388 mutex->id = osMutexNew(&mutex->attr); 00389 if (mutex->id == NULL) { 00390 MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_mutex_new error\n", (u32_t)mutex); 00391 return ERR_MEM; 00392 } 00393 00394 return ERR_OK; 00395 } 00396 00397 /** Lock a mutex 00398 * @param mutex the mutex to lock */ 00399 void sys_mutex_lock(sys_mutex_t *mutex) { 00400 if (osMutexAcquire(mutex->id, osWaitForever) != osOK) 00401 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "sys_mutex_lock error\n", (u32_t)mutex); 00402 } 00403 00404 /** Unlock a mutex 00405 * @param mutex the mutex to unlock */ 00406 void sys_mutex_unlock(sys_mutex_t *mutex) { 00407 if (osMutexRelease(mutex->id) != osOK) 00408 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_UNLOCK_FAILED), "sys_mutex_unlock error\n", (u32_t)mutex); 00409 } 00410 00411 /** Delete a mutex 00412 * @param mutex the mutex to delete */ 00413 void sys_mutex_free(sys_mutex_t *mutex) {} 00414 00415 /*---------------------------------------------------------------------------* 00416 * Routine: sys_init 00417 *---------------------------------------------------------------------------* 00418 * Description: 00419 * Initialize sys arch 00420 *---------------------------------------------------------------------------*/ 00421 osMutexId_t lwip_sys_mutex; 00422 osMutexAttr_t lwip_sys_mutex_attr; 00423 mbed_rtos_storage_mutex_t lwip_sys_mutex_data; 00424 00425 void sys_init(void) { 00426 lwip_sys_mutex_attr.name = "lwip_sys_mutex"; 00427 lwip_sys_mutex_attr.cb_mem = &lwip_sys_mutex_data; 00428 lwip_sys_mutex_attr.cb_size = sizeof(lwip_sys_mutex_data); 00429 lwip_sys_mutex = osMutexNew(&lwip_sys_mutex_attr); 00430 if (lwip_sys_mutex == NULL) 00431 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_INITIALIZATION_FAILED), "sys_init error, mutex initialization failed\n"); 00432 } 00433 00434 /*---------------------------------------------------------------------------* 00435 * Routine: sys_jiffies 00436 *---------------------------------------------------------------------------* 00437 * Description: 00438 * Used by PPP as a timestamp-ish value 00439 *---------------------------------------------------------------------------*/ 00440 u32_t sys_jiffies(void) { 00441 return osKernelGetTickCount(); 00442 } 00443 00444 /*---------------------------------------------------------------------------* 00445 * Routine: sys_arch_protect 00446 *---------------------------------------------------------------------------* 00447 * Description: 00448 * This optional function does a "fast" critical region protection and 00449 * returns the previous protection level. This function is only called 00450 * during very short critical regions. An embedded system which supports 00451 * ISR-based drivers might want to implement this function by disabling 00452 * interrupts. Task-based systems might want to implement this by using 00453 * a mutex or disabling tasking. This function should support recursive 00454 * calls from the same task or interrupt. In other words, 00455 * sys_arch_protect() could be called while already protected. In 00456 * that case the return value indicates that it is already protected. 00457 * 00458 * sys_arch_protect() is only required if your port is supporting an 00459 * operating system. 00460 * Outputs: 00461 * sys_prot_t -- Previous protection level (not used here) 00462 *---------------------------------------------------------------------------*/ 00463 sys_prot_t sys_arch_protect(void) { 00464 if (osMutexAcquire(lwip_sys_mutex, osWaitForever) != osOK) 00465 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "sys_arch_protect error\n"); 00466 return (sys_prot_t) 1; 00467 } 00468 00469 /*---------------------------------------------------------------------------* 00470 * Routine: sys_arch_unprotect 00471 *---------------------------------------------------------------------------* 00472 * Description: 00473 * This optional function does a "fast" set of critical region 00474 * protection to the value specified by pval. See the documentation for 00475 * sys_arch_protect() for more information. This function is only 00476 * required if your port is supporting an operating system. 00477 * Inputs: 00478 * sys_prot_t -- Previous protection level (not used here) 00479 *---------------------------------------------------------------------------*/ 00480 void sys_arch_unprotect(sys_prot_t p) { 00481 if (osMutexRelease(lwip_sys_mutex) != osOK) 00482 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_UNLOCK_FAILED), "sys_arch_unprotect error\n"); 00483 } 00484 00485 u32_t sys_now(void) { 00486 return osKernelGetTickCount(); 00487 } 00488 00489 void sys_msleep(u32_t ms) { 00490 osDelay(ms); 00491 } 00492 00493 osThreadId_t lwip_tcpip_thread_id = 0; 00494 00495 void sys_tcpip_thread_set(void) 00496 { 00497 lwip_tcpip_thread_id = osThreadGetId(); 00498 } 00499 00500 bool sys_tcpip_thread_check(void) 00501 { 00502 return osThreadGetId() == lwip_tcpip_thread_id; 00503 } 00504 00505 // Keep a pool of thread structures 00506 static int thread_pool_index = 0; 00507 static sys_thread_data_t thread_pool[SYS_THREAD_POOL_N]; 00508 00509 /*---------------------------------------------------------------------------* 00510 * Routine: sys_thread_new 00511 *---------------------------------------------------------------------------* 00512 * Description: 00513 * Starts a new thread with priority "prio" that will begin its 00514 * execution in the function "thread()". The "arg" argument will be 00515 * passed as an argument to the thread() function. The id of the new 00516 * thread is returned. Both the id and the priority are system 00517 * dependent. 00518 * Inputs: 00519 * char *name -- Name of thread 00520 * void (*thread)(void *arg) -- Pointer to function to run. 00521 * void *arg -- Argument passed into function 00522 * int stacksize -- Required stack amount in bytes 00523 * int priority -- Thread priority 00524 * Outputs: 00525 * sys_thread_t -- Pointer to thread handle. 00526 *---------------------------------------------------------------------------*/ 00527 #ifndef MBED_TZ_DEFAULT_ACCESS 00528 #define MBED_TZ_DEFAULT_ACCESS 0 00529 #endif 00530 00531 sys_thread_t sys_thread_new(const char *pcName, 00532 void (*thread)(void *arg), 00533 void *arg, int stacksize, int priority) { 00534 LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName)); 00535 00536 if (thread_pool_index >= SYS_THREAD_POOL_N) 00537 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_THREAD_CREATE_FAILED), "sys_thread_new number error\n", thread_pool_index); 00538 sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; 00539 thread_pool_index++; 00540 00541 memset(t, 0, sizeof(*t)); 00542 t->attr.name = pcName ? pcName : "lwip_unnamed_thread"; 00543 t->attr.priority = (osPriority_t)priority; 00544 t->attr.cb_size = sizeof(t->data); 00545 t->attr.cb_mem = &t->data; 00546 t->attr.stack_size = stacksize; 00547 t->attr.stack_mem = malloc(stacksize); 00548 t->attr.tz_module = MBED_TZ_DEFAULT_ACCESS; 00549 if (t->attr.stack_mem == NULL) { 00550 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_OUT_OF_MEMORY), "unable to allocate thread stack\n", stacksize); 00551 } 00552 t->id = osThreadNew((osThreadFunc_t)thread, arg, &t->attr); 00553 if (t->id == NULL) 00554 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_THREAD_CREATE_FAILED), "sys_thread_new create error\n"); 00555 00556 return t; 00557 } 00558 00559 #endif 00560 00561 #ifdef LWIP_DEBUG 00562 00563 #include <stdbool.h> 00564 00565 #if MBED_CONF_LWIP_USE_MBED_TRACE 00566 #include "mbed-trace/mbed_trace.h" 00567 00568 void lwip_mbed_tracef_debug(const char *fmt, ...) 00569 { 00570 va_list ap; 00571 va_start(ap, fmt); 00572 mbed_vtracef(TRACE_LEVEL_DEBUG, "lwIP", fmt, ap); 00573 va_end(ap); 00574 } 00575 00576 void lwip_mbed_tracef_warn(const char *fmt, ...) 00577 { 00578 va_list ap; 00579 va_start(ap, fmt); 00580 mbed_vtracef(TRACE_LEVEL_WARN, "lwIP", fmt, ap); 00581 va_end(ap); 00582 } 00583 00584 void lwip_mbed_tracef_error(const char *fmt, ...) 00585 { 00586 va_list ap; 00587 va_start(ap, fmt); 00588 mbed_vtracef(TRACE_LEVEL_ERROR, "lwIP", fmt, ap); 00589 va_end(ap); 00590 } 00591 00592 void lwip_mbed_assert_fail(const char *msg, const char *func, const char *file, unsigned int line) 00593 { 00594 mbed_tracef(TRACE_LEVEL_ERROR, "lwIP", "Assertion failed: %s, function %s, file %s, line %u.", msg, func, file, line); 00595 exit(EXIT_FAILURE); // XXX how about abort? mbed_assert uses exit, so follow suit 00596 } 00597 #else // MBED_CONF_LWIP_USE_MBED_TRACE 00598 00599 /** \brief Displays an error message on assertion 00600 00601 This function will display an error message on an assertion 00602 to the debug output. 00603 00604 \param[in] msg Error message to display 00605 \param[in] line Line number in file with error 00606 \param[in] file Filename with error 00607 */ 00608 void assert_printf(char *msg, int line, char *file) { 00609 if (msg) 00610 error("%s:%d in file %s\n", msg, line, file); 00611 else 00612 error("LWIP ASSERT\n"); 00613 } 00614 #endif // MBED_CONF_LWIP_USE_MBED_TRACE 00615 00616 #if TRACE_TO_ASCII_HEX_DUMP 00617 void trace_to_ascii_hex_dump(char *prefix, int len, char *data) 00618 { 00619 int line_len = 0; 00620 00621 for (int i = 0; i < len; i++) { 00622 if ((line_len % 16) == 0) { 00623 if (line_len != 0) { 00624 LWIP_PLATFORM_DIAG(("\n")); 00625 } 00626 LWIP_PLATFORM_DIAG(("%s %06x", prefix, line_len)); 00627 } 00628 line_len++; 00629 LWIP_PLATFORM_DIAG((" %02x", data[i])); 00630 } 00631 LWIP_PLATFORM_DIAG(("\n")); 00632 } 00633 #endif 00634 00635 #endif /* LWIP_DEBUG */
Generated on Tue Aug 9 2022 00:37:11 by
