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