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 error("sys_mbox_new size error\n"); 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 error("sys_mbox_new create error\n"); 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 error("sys_mbox_free error\n"); 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 return ERR_MEM; 00199 00200 int state = osKernelLock(); 00201 00202 mbox->queue[mbox->post_idx % MB_SIZE] = msg; 00203 mbox->post_idx += 1; 00204 00205 osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT); 00206 if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1) 00207 osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT); 00208 00209 osKernelRestoreLock(state); 00210 return ERR_OK; 00211 } 00212 00213 /*---------------------------------------------------------------------------* 00214 * Routine: sys_arch_mbox_fetch 00215 *---------------------------------------------------------------------------* 00216 * Description: 00217 * Blocks the thread until a message arrives in the mailbox, but does 00218 * not block the thread longer than "timeout" milliseconds (similar to 00219 * the sys_arch_sem_wait() function). The "msg" argument is a result 00220 * parameter that is set by the function (i.e., by doing "*msg = 00221 * ptr"). The "msg" parameter maybe NULL to indicate that the message 00222 * should be dropped. 00223 * 00224 * The return values are the same as for the sys_arch_sem_wait() function: 00225 * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a 00226 * timeout. 00227 * 00228 * Note that a function with a similar name, sys_mbox_fetch(), is 00229 * implemented by lwIP. 00230 * Inputs: 00231 * sys_mbox_t mbox -- Handle of mailbox 00232 * void **msg -- Pointer to pointer to msg received 00233 * u32_t timeout -- Number of milliseconds until timeout 00234 * Outputs: 00235 * u32_t -- SYS_ARCH_TIMEOUT if timeout, else number 00236 * of milliseconds until received. 00237 *---------------------------------------------------------------------------*/ 00238 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { 00239 uint32_t start = osKernelGetTickCount(); 00240 uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, 00241 osFlagsWaitAny | osFlagsNoClear, (timeout ? timeout : osWaitForever)); 00242 if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) 00243 return SYS_ARCH_TIMEOUT; 00244 00245 int state = osKernelLock(); 00246 00247 if (msg) 00248 *msg = mbox->queue[mbox->fetch_idx % MB_SIZE]; 00249 mbox->fetch_idx += 1; 00250 00251 osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); 00252 if (mbox->post_idx == mbox->fetch_idx) 00253 osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT); 00254 00255 osKernelRestoreLock(state); 00256 return osKernelGetTickCount() - start; 00257 } 00258 00259 /*---------------------------------------------------------------------------* 00260 * Routine: sys_arch_mbox_tryfetch 00261 *---------------------------------------------------------------------------* 00262 * Description: 00263 * Similar to sys_arch_mbox_fetch, but if message is not ready 00264 * immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is 00265 * returned. 00266 * Inputs: 00267 * sys_mbox_t mbox -- Handle of mailbox 00268 * void **msg -- Pointer to pointer to msg received 00269 * Outputs: 00270 * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise, 00271 * return ERR_OK. 00272 *---------------------------------------------------------------------------*/ 00273 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { 00274 uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, 00275 osFlagsWaitAny | osFlagsNoClear, 0); 00276 if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) 00277 return SYS_MBOX_EMPTY; 00278 00279 int state = osKernelLock(); 00280 00281 if (msg) 00282 *msg = mbox->queue[mbox->fetch_idx % MB_SIZE]; 00283 mbox->fetch_idx += 1; 00284 00285 osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); 00286 if (mbox->post_idx == mbox->fetch_idx) 00287 osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT); 00288 00289 osKernelRestoreLock(state); 00290 return ERR_OK; 00291 } 00292 00293 /*---------------------------------------------------------------------------* 00294 * Routine: sys_sem_new 00295 *---------------------------------------------------------------------------* 00296 * Description: 00297 * Creates and returns a new semaphore. The "ucCount" argument specifies 00298 * the initial state of the semaphore. 00299 * NOTE: Currently this routine only creates counts of 1 or 0 00300 * Inputs: 00301 * sys_sem_t sem -- Handle of semaphore 00302 * u8_t count -- Initial count of semaphore 00303 * Outputs: 00304 * err_t -- ERR_OK if semaphore created 00305 *---------------------------------------------------------------------------*/ 00306 err_t sys_sem_new(sys_sem_t *sem, u8_t count) { 00307 memset(sem, 0, sizeof(*sem)); 00308 sem->attr.cb_mem = &sem->data; 00309 sem->attr.cb_size = sizeof(sem->data); 00310 sem->id = osSemaphoreNew(UINT16_MAX, count, &sem->attr); 00311 if (sem->id == NULL) 00312 error("sys_sem_new create error\n"); 00313 00314 return ERR_OK; 00315 } 00316 00317 /*---------------------------------------------------------------------------* 00318 * Routine: sys_arch_sem_wait 00319 *---------------------------------------------------------------------------* 00320 * Description: 00321 * Blocks the thread while waiting for the semaphore to be 00322 * signaled. If the "timeout" argument is non-zero, the thread should 00323 * only be blocked for the specified time (measured in 00324 * milliseconds). 00325 * 00326 * If the timeout argument is non-zero, the return value is the number of 00327 * milliseconds spent waiting for the semaphore to be signaled. If the 00328 * semaphore wasn't signaled within the specified time, the return value is 00329 * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore 00330 * (i.e., it was already signaled), the function may return zero. 00331 * 00332 * Notice that lwIP implements a function with a similar name, 00333 * sys_sem_wait(), that uses the sys_arch_sem_wait() function. 00334 * Inputs: 00335 * sys_sem_t sem -- Semaphore to wait on 00336 * u32_t timeout -- Number of milliseconds until timeout 00337 * Outputs: 00338 * u32_t -- Time elapsed or SYS_ARCH_TIMEOUT. 00339 *---------------------------------------------------------------------------*/ 00340 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { 00341 u32_t start = osKernelGetTickCount(); 00342 00343 if (osSemaphoreAcquire(sem->id, (timeout != 0)?(timeout):(osWaitForever)) != osOK) 00344 return SYS_ARCH_TIMEOUT; 00345 00346 return osKernelGetTickCount() - start; 00347 } 00348 00349 /*---------------------------------------------------------------------------* 00350 * Routine: sys_sem_signal 00351 *---------------------------------------------------------------------------* 00352 * Description: 00353 * Signals (releases) a semaphore 00354 * Inputs: 00355 * sys_sem_t sem -- Semaphore to signal 00356 *---------------------------------------------------------------------------*/ 00357 void sys_sem_signal(sys_sem_t *data) { 00358 if (osSemaphoreRelease(data->id) != osOK) 00359 mbed_die(); /* Can be called by ISR do not use printf */ 00360 } 00361 00362 /*---------------------------------------------------------------------------* 00363 * Routine: sys_sem_free 00364 *---------------------------------------------------------------------------* 00365 * Description: 00366 * Deallocates a semaphore 00367 * Inputs: 00368 * sys_sem_t sem -- Semaphore to free 00369 *---------------------------------------------------------------------------*/ 00370 void sys_sem_free(sys_sem_t *sem) {} 00371 00372 /** Create a new mutex 00373 * @param mutex pointer to the mutex to create 00374 * @return a new mutex */ 00375 err_t sys_mutex_new(sys_mutex_t *mutex) { 00376 memset(mutex, 0, sizeof(*mutex)); 00377 mutex->attr.name = "lwip_mutex"; 00378 mutex->attr.cb_mem = &mutex->data; 00379 mutex->attr.cb_size = sizeof(mutex->data); 00380 mutex->id = osMutexNew(&mutex->attr); 00381 if (mutex->id == NULL) 00382 return ERR_MEM; 00383 00384 return ERR_OK; 00385 } 00386 00387 /** Lock a mutex 00388 * @param mutex the mutex to lock */ 00389 void sys_mutex_lock(sys_mutex_t *mutex) { 00390 if (osMutexAcquire(mutex->id, osWaitForever) != osOK) 00391 error("sys_mutex_lock error\n"); 00392 } 00393 00394 /** Unlock a mutex 00395 * @param mutex the mutex to unlock */ 00396 void sys_mutex_unlock(sys_mutex_t *mutex) { 00397 if (osMutexRelease(mutex->id) != osOK) 00398 error("sys_mutex_unlock error\n"); 00399 } 00400 00401 /** Delete a mutex 00402 * @param mutex the mutex to delete */ 00403 void sys_mutex_free(sys_mutex_t *mutex) {} 00404 00405 /*---------------------------------------------------------------------------* 00406 * Routine: sys_init 00407 *---------------------------------------------------------------------------* 00408 * Description: 00409 * Initialize sys arch 00410 *---------------------------------------------------------------------------*/ 00411 osMutexId_t lwip_sys_mutex; 00412 osMutexAttr_t lwip_sys_mutex_attr; 00413 mbed_rtos_storage_mutex_t lwip_sys_mutex_data; 00414 00415 void sys_init(void) { 00416 lwip_sys_mutex_attr.name = "lwip_sys_mutex"; 00417 lwip_sys_mutex_attr.cb_mem = &lwip_sys_mutex_data; 00418 lwip_sys_mutex_attr.cb_size = sizeof(lwip_sys_mutex_data); 00419 lwip_sys_mutex = osMutexNew(&lwip_sys_mutex_attr); 00420 if (lwip_sys_mutex == NULL) 00421 error("sys_init error\n"); 00422 } 00423 00424 /*---------------------------------------------------------------------------* 00425 * Routine: sys_jiffies 00426 *---------------------------------------------------------------------------* 00427 * Description: 00428 * Used by PPP as a timestamp-ish value 00429 *---------------------------------------------------------------------------*/ 00430 u32_t sys_jiffies(void) { 00431 return osKernelGetTickCount(); 00432 } 00433 00434 /*---------------------------------------------------------------------------* 00435 * Routine: sys_arch_protect 00436 *---------------------------------------------------------------------------* 00437 * Description: 00438 * This optional function does a "fast" critical region protection and 00439 * returns the previous protection level. This function is only called 00440 * during very short critical regions. An embedded system which supports 00441 * ISR-based drivers might want to implement this function by disabling 00442 * interrupts. Task-based systems might want to implement this by using 00443 * a mutex or disabling tasking. This function should support recursive 00444 * calls from the same task or interrupt. In other words, 00445 * sys_arch_protect() could be called while already protected. In 00446 * that case the return value indicates that it is already protected. 00447 * 00448 * sys_arch_protect() is only required if your port is supporting an 00449 * operating system. 00450 * Outputs: 00451 * sys_prot_t -- Previous protection level (not used here) 00452 *---------------------------------------------------------------------------*/ 00453 sys_prot_t sys_arch_protect(void) { 00454 if (osMutexAcquire(lwip_sys_mutex, osWaitForever) != osOK) 00455 error("sys_arch_protect error\n"); 00456 return (sys_prot_t) 1; 00457 } 00458 00459 /*---------------------------------------------------------------------------* 00460 * Routine: sys_arch_unprotect 00461 *---------------------------------------------------------------------------* 00462 * Description: 00463 * This optional function does a "fast" set of critical region 00464 * protection to the value specified by pval. See the documentation for 00465 * sys_arch_protect() for more information. This function is only 00466 * required if your port is supporting an operating system. 00467 * Inputs: 00468 * sys_prot_t -- Previous protection level (not used here) 00469 *---------------------------------------------------------------------------*/ 00470 void sys_arch_unprotect(sys_prot_t p) { 00471 if (osMutexRelease(lwip_sys_mutex) != osOK) 00472 error("sys_arch_unprotect error\n"); 00473 } 00474 00475 u32_t sys_now(void) { 00476 return osKernelGetTickCount(); 00477 } 00478 00479 void sys_msleep(u32_t ms) { 00480 osDelay(ms); 00481 } 00482 00483 osThreadId_t lwip_tcpip_thread_id = 0; 00484 00485 void sys_tcpip_thread_set(void) 00486 { 00487 lwip_tcpip_thread_id = osThreadGetId(); 00488 } 00489 00490 bool sys_tcpip_thread_check(void) 00491 { 00492 return osThreadGetId() == lwip_tcpip_thread_id; 00493 } 00494 00495 // Keep a pool of thread structures 00496 static int thread_pool_index = 0; 00497 static sys_thread_data_t thread_pool[SYS_THREAD_POOL_N]; 00498 00499 /*---------------------------------------------------------------------------* 00500 * Routine: sys_thread_new 00501 *---------------------------------------------------------------------------* 00502 * Description: 00503 * Starts a new thread with priority "prio" that will begin its 00504 * execution in the function "thread()". The "arg" argument will be 00505 * passed as an argument to the thread() function. The id of the new 00506 * thread is returned. Both the id and the priority are system 00507 * dependent. 00508 * Inputs: 00509 * char *name -- Name of thread 00510 * void (*thread)(void *arg) -- Pointer to function to run. 00511 * void *arg -- Argument passed into function 00512 * int stacksize -- Required stack amount in bytes 00513 * int priority -- Thread priority 00514 * Outputs: 00515 * sys_thread_t -- Pointer to thread handle. 00516 *---------------------------------------------------------------------------*/ 00517 #ifndef MBED_TZ_DEFAULT_ACCESS 00518 #define MBED_TZ_DEFAULT_ACCESS 0 00519 #endif 00520 00521 sys_thread_t sys_thread_new(const char *pcName, 00522 void (*thread)(void *arg), 00523 void *arg, int stacksize, int priority) { 00524 LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName)); 00525 00526 if (thread_pool_index >= SYS_THREAD_POOL_N) 00527 error("sys_thread_new number error\n"); 00528 sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; 00529 thread_pool_index++; 00530 00531 memset(t, 0, sizeof(*t)); 00532 t->attr.name = pcName ? pcName : "lwip_unnamed_thread"; 00533 t->attr.priority = (osPriority_t)priority; 00534 t->attr.cb_size = sizeof(t->data); 00535 t->attr.cb_mem = &t->data; 00536 t->attr.stack_size = stacksize; 00537 t->attr.stack_mem = malloc(stacksize); 00538 t->attr.tz_module = MBED_TZ_DEFAULT_ACCESS; 00539 if (t->attr.stack_mem == NULL) { 00540 error("Error allocating the stack memory"); 00541 } 00542 t->id = osThreadNew((osThreadFunc_t)thread, arg, &t->attr); 00543 if (t->id == NULL) 00544 error("sys_thread_new create error\n"); 00545 00546 return t; 00547 } 00548 00549 #endif 00550 00551 #ifdef LWIP_DEBUG 00552 00553 #include <stdbool.h> 00554 00555 #if MBED_CONF_LWIP_USE_MBED_TRACE 00556 #include "mbed-trace/mbed_trace.h" 00557 00558 void lwip_mbed_tracef_debug(const char *fmt, ...) 00559 { 00560 va_list ap; 00561 va_start(ap, fmt); 00562 mbed_vtracef(TRACE_LEVEL_DEBUG, "lwIP", fmt, ap); 00563 va_end(ap); 00564 } 00565 00566 void lwip_mbed_tracef_warn(const char *fmt, ...) 00567 { 00568 va_list ap; 00569 va_start(ap, fmt); 00570 mbed_vtracef(TRACE_LEVEL_WARN, "lwIP", fmt, ap); 00571 va_end(ap); 00572 } 00573 00574 void lwip_mbed_tracef_error(const char *fmt, ...) 00575 { 00576 va_list ap; 00577 va_start(ap, fmt); 00578 mbed_vtracef(TRACE_LEVEL_ERROR, "lwIP", fmt, ap); 00579 va_end(ap); 00580 } 00581 00582 void lwip_mbed_assert_fail(const char *msg, const char *func, const char *file, unsigned int line) 00583 { 00584 mbed_tracef(TRACE_LEVEL_ERROR, "lwIP", "Assertion failed: %s, function %s, file %s, line %u.", msg, func, file, line); 00585 exit(EXIT_FAILURE); // XXX how about abort? mbed_assert uses exit, so follow suit 00586 } 00587 #else // MBED_CONF_LWIP_USE_MBED_TRACE 00588 00589 /** \brief Displays an error message on assertion 00590 00591 This function will display an error message on an assertion 00592 to the debug output. 00593 00594 \param[in] msg Error message to display 00595 \param[in] line Line number in file with error 00596 \param[in] file Filename with error 00597 */ 00598 void assert_printf(char *msg, int line, char *file) { 00599 if (msg) 00600 error("%s:%d in file %s\n", msg, line, file); 00601 else 00602 error("LWIP ASSERT\n"); 00603 } 00604 #endif // MBED_CONF_LWIP_USE_MBED_TRACE 00605 00606 #if TRACE_TO_ASCII_HEX_DUMP 00607 void trace_to_ascii_hex_dump(char *prefix, int len, char *data) 00608 { 00609 int line_len = 0; 00610 00611 for (int i = 0; i < len; i++) { 00612 if ((line_len % 16) == 0) { 00613 if (line_len != 0) { 00614 LWIP_PLATFORM_DIAG(("\n")); 00615 } 00616 LWIP_PLATFORM_DIAG(("%s %06x", prefix, line_len)); 00617 } 00618 line_len++; 00619 LWIP_PLATFORM_DIAG((" %02x", data[i])); 00620 } 00621 LWIP_PLATFORM_DIAG(("\n")); 00622 } 00623 #endif 00624 00625 #endif /* LWIP_DEBUG */
Generated on Tue Jul 12 2022 12:44:49 by
