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