Adapted to Lora Semtech + Nucleo
Dependents: LoRaWAN-lmic-app LoRaWAN-lmic-app LoRaWAN-test-10secs LoRaPersonalizedDeviceForEverynet ... more
Fork of lwip_ppp_ethernet by
sys_arch.cpp
00001 /* sysarch.cpp */ 00002 /* 00003 Copyright (C) 2012 ARM Limited. 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy of 00006 this software and associated documentation files (the "Software"), to deal in 00007 the Software without restriction, including without limitation the rights to 00008 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 00009 of the Software, and to permit persons to whom the Software is furnished to do 00010 so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in all 00013 copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00021 SOFTWARE. 00022 */ 00023 00024 #define __DEBUG__ 0 00025 #ifndef __MODULE__ 00026 #define __MODULE__ "sys_arch.cpp" 00027 #endif 00028 00029 extern "C" 00030 { 00031 #include "lwip/opt.h" 00032 #include "lwip/def.h" 00033 #include "lwip/sys.h" 00034 #include "lwip/arch.h" 00035 #include "cc.h" 00036 #include "sys_arch.h" 00037 } 00038 00039 #include "core/fwk.h" 00040 #include "rtos.h" 00041 #include "mbed.h" //From mbed library 00042 00043 /* 00044 From http://lwip.wikia.com/wiki/Porting_for_an_OS: 00045 00046 The sys_arch provides semaphores and mailboxes to lwIP. For the full 00047 lwIP functionality, multiple threads support can be implemented in the 00048 sys_arch, but this is not required for the basic lwIP functionality. 00049 */ 00050 00051 extern "C" 00052 /* 00053 The file is .cpp to be able to use the C++ abstraction of Mutexes, Semaphores, etc. 00054 however it should be linked in a C-fashion 00055 */ 00056 { 00057 00058 #if SYS_LIGHTWEIGHT_PROT == 0 00059 #error "SYS_LIGHTWEIGHT_PROT must be set" 00060 #endif 00061 00062 #if SYS_LIGHTWEIGHT_PROT 00063 //Critical regions protection 00064 static Mutex sys_arch_protect_mtx; 00065 00066 sys_prot_t sys_arch_protect(void) 00067 { 00068 00069 sys_arch_protect_mtx.lock(); 00070 00071 return 0; 00072 } 00073 00074 void sys_arch_unprotect(sys_prot_t pval) 00075 { 00076 00077 LWIP_UNUSED_ARG(pval); 00078 sys_arch_protect_mtx.unlock(); 00079 00080 } 00081 #endif 00082 00083 //Mutexes 00084 00085 /** Create a new mutex 00086 * @param mutex pointer to the mutex to create 00087 * @return a new mutex */ 00088 err_t sys_mutex_new(sys_mutex_t *pMtx) 00089 { 00090 00091 SYS_ARCH_DECL_PROTECT(lev); 00092 DBG("Trying to create new mutex"); 00093 00094 SYS_ARCH_PROTECT(lev); //Protect this section 00095 pMtx->pMtx = new Mutex(); 00096 SYS_ARCH_UNPROTECT(lev); 00097 00098 if(pMtx->pMtx == NULL) 00099 { 00100 DBG("No mem"); 00101 00102 return ERR_MEM; 00103 } 00104 00105 pMtx->valid = true; 00106 00107 DBG("mutex created OK"); 00108 00109 return ERR_OK; //Return the semaphore 00110 } 00111 00112 /** Lock a mutex 00113 * @param mutex the mutex to lock */ 00114 void sys_mutex_lock(sys_mutex_t *pMtx) 00115 { 00116 00117 ((Mutex*)(pMtx->pMtx))->lock(); 00118 00119 } 00120 00121 /** Unlock a mutex 00122 * @param mutex the mutex to unlock */ 00123 void sys_mutex_unlock(sys_mutex_t *pMtx) 00124 { 00125 00126 ((Mutex*)(pMtx->pMtx))->unlock(); 00127 00128 } 00129 00130 /** Delete a mutex 00131 * @param mutex the mutex to delete */ 00132 void sys_mutex_free(sys_mutex_t *pMtx) 00133 { 00134 00135 SYS_ARCH_DECL_PROTECT(lev); 00136 SYS_ARCH_PROTECT(lev); //Protect this section 00137 delete ((Mutex*)(pMtx->pMtx)); 00138 SYS_ARCH_UNPROTECT(lev); 00139 00140 } 00141 00142 /** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ 00143 int sys_mutex_valid(sys_mutex_t *pMtx) 00144 { 00145 00146 if (pMtx->pMtx != NULL) 00147 { 00148 00149 return pMtx->valid; 00150 } 00151 00152 return false; 00153 } 00154 00155 /** Set a mutex invalid so that sys_mutex_valid returns 0 */ 00156 void sys_mutex_set_invalid(sys_mutex_t *pMtx) 00157 { 00158 00159 pMtx->valid = false; 00160 00161 } 00162 00163 //Semaphores 00164 00165 /* 00166 The implementation reserves a pool of semaphores that can be used by 00167 LwIP in order to only use static allocation 00168 */ 00169 00170 //static sys_sem sys_sem_pool[LWIP_SEMAPHORES_COUNT] = { 0 }; 00171 00172 /* 00173 Creates and returns a new semaphore. The count argument specifies the 00174 initial state of the semaphore. Returns the semaphore, or SYS_SEM_NULL 00175 on error. 00176 */ 00177 err_t sys_sem_new_mul(sys_sem_t *pSem, u8_t size, u8_t count) 00178 { 00179 00180 SYS_ARCH_DECL_PROTECT(lev); 00181 DBG("Trying to create new semaphore of size=%d", size); 00182 00183 SYS_ARCH_PROTECT(lev); //Protect this section 00184 pSem->pSphre = new Semaphore(size); 00185 SYS_ARCH_UNPROTECT(lev); 00186 if(pSem->pSphre == NULL) 00187 { 00188 ERR("Failed!"); 00189 return ERR_MEM; 00190 } 00191 00192 while(count < size) 00193 { 00194 ((Semaphore*)(pSem->pSphre))->wait(); 00195 count++; 00196 } 00197 pSem->valid = true; 00198 00199 00200 return ERR_OK; //Return the semaphore 00201 } 00202 00203 00204 /* 00205 Creates and returns a new semaphore. The count argument specifies the 00206 initial state of the semaphore. Returns the semaphore, or SYS_SEM_NULL 00207 on error. 00208 */ 00209 err_t sys_sem_new(sys_sem_t *pSem, u8_t count) 00210 { 00211 00212 SYS_ARCH_DECL_PROTECT(lev); 00213 DBG("Trying to create new semaphore of count=%d", count); 00214 00215 SYS_ARCH_PROTECT(lev); //Protect this section 00216 pSem->pSphre = new Semaphore(1); 00217 SYS_ARCH_UNPROTECT(lev); 00218 if(pSem->pSphre == NULL) 00219 { 00220 ERR("Failed!"); 00221 return ERR_MEM; 00222 } 00223 00224 if(!count) 00225 { 00226 ((Semaphore*)(pSem->pSphre))->wait(); 00227 } 00228 pSem->valid = true; 00229 00230 00231 return ERR_OK; //Return the semaphore 00232 } 00233 00234 /* 00235 Frees a semaphore created by sys_sem_new. Since these two functions 00236 provide the entry and exit point for all semaphores used by lwIP, you 00237 have great flexibility in how these are allocated and deallocated (for 00238 example, from the heap, a memory pool, a semaphore pool, etc). 00239 */ 00240 void sys_sem_free(sys_sem_t *pSem) 00241 { 00242 SYS_ARCH_DECL_PROTECT(lev); 00243 DBG("Deleting semaphore"); 00244 SYS_ARCH_PROTECT(lev); //Protect this section 00245 delete ((Semaphore*)(pSem->pSphre)); 00246 SYS_ARCH_UNPROTECT(lev); 00247 00248 } 00249 00250 /* 00251 Signals (or releases) a semaphore. 00252 */ 00253 void sys_sem_signal(sys_sem_t* pSem) 00254 { 00255 00256 ((Semaphore*)(pSem->pSphre))->release(); //Produce (i.e. release) a resource 00257 00258 } 00259 00260 /* 00261 Blocks the thread while waiting for the semaphore to be signaled. The 00262 timeout parameter specifies how many milliseconds the function should 00263 block before returning; if the function times out, it should return 00264 SYS_ARCH_TIMEOUT. If timeout=0, then the function should block 00265 indefinitely. If the function acquires the semaphore, it should return 00266 how many milliseconds expired while waiting for the semaphore. The 00267 function may return 0 if the semaphore was immediately available. 00268 */ 00269 u32_t sys_arch_sem_wait(sys_sem_t* pSem, u32_t timeout) 00270 { 00271 00272 int ret; 00273 Timer t; 00274 uint32_t timeout_sphre; 00275 int time_spent; 00276 00277 timeout_sphre = (timeout != 0) ? timeout : osWaitForever /*block indefinitely*/; 00278 00279 t.start(); 00280 ret = ((Semaphore*)(pSem->pSphre))->wait(timeout_sphre); 00281 if(ret == 0) 00282 { 00283 00284 return SYS_ARCH_TIMEOUT; 00285 } 00286 time_spent = t.read_ms(); 00287 00288 return time_spent; 00289 } 00290 00291 /** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ 00292 int sys_sem_valid(sys_sem_t *pSem) 00293 { 00294 00295 if (pSem->pSphre != NULL) 00296 { 00297 00298 return (pSem->valid); 00299 } 00300 00301 return false; 00302 } 00303 00304 /** Set a semaphore invalid so that sys_sem_valid returns 0 */ 00305 void sys_sem_set_invalid(sys_sem_t *pSem) 00306 { 00307 00308 pSem->valid = false; 00309 00310 } 00311 00312 //Mailboxes 00313 00314 /* 00315 The implementation reserves a pool of mailboxes of generic (void*) type that can be used by 00316 LwIP in order to only use static allocation 00317 */ 00318 00319 #define QUEUE_SIZE 8 00320 #define SYS_MBOX_SIZE QUEUE_SIZE 00321 #if 0 00322 /* 00323 Returns a new mailbox, or SYS_MBOX_NULL on error. 00324 */ 00325 err_t sys_mbox_new(sys_mbox_t *pMbox, int size) 00326 { 00327 00328 SYS_ARCH_DECL_PROTECT(lev); 00329 ERR("Trying to create new queue of size %d", size); 00330 00331 SYS_ARCH_PROTECT(lev); //Protect this section 00332 if(size > QUEUE_SIZE) 00333 { 00334 ERR("Queue size > QUEUE_SIZE"); 00335 } 00336 pMbox->pQueue = new Queue<void,QUEUE_SIZE>(); 00337 SYS_ARCH_UNPROTECT(lev); 00338 if(pMbox->pQueue == NULL) 00339 { 00340 00341 return ERR_MEM; 00342 } 00343 pMbox->valid = true; 00344 00345 00346 return ERR_OK; //Return the mailbox 00347 } 00348 00349 /* 00350 Deallocates a mailbox. If there are messages still present in the 00351 mailbox when the mailbox is deallocated, it is an indication of a 00352 programming error in lwIP and the developer should be notified. 00353 */ 00354 void sys_mbox_free(sys_mbox_t* pMbox) 00355 { 00356 ERR("WHY??"); 00357 00358 SYS_ARCH_DECL_PROTECT(lev); 00359 SYS_ARCH_PROTECT(lev); //Protect this section 00360 delete ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue)); 00361 SYS_ARCH_UNPROTECT(lev); 00362 00363 } 00364 00365 /* 00366 Posts the "msg" to the mailbox. 00367 */ 00368 void sys_mbox_post(sys_mbox_t* pMbox, void *msg) 00369 { 00370 00371 if(msg == NULL) 00372 { 00373 ERR("NULL"); 00374 Thread::wait(100); 00375 } 00376 00377 ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->put(msg, osWaitForever); 00378 00379 } 00380 00381 /* 00382 Blocks the thread until a message arrives in the mailbox, but does not 00383 block the thread longer than timeout milliseconds (similar to the 00384 sys_arch_sem_wait() function). The msg argument is a pointer to the 00385 message in the mailbox and may be NULL to indicate that the message 00386 should be dropped. This should return either SYS_ARCH_TIMEOUT or the 00387 number of milliseconds elapsed waiting for a message. 00388 */ 00389 u32_t sys_arch_mbox_fetch(sys_mbox_t* pMbox, void **msg, u32_t timeout) 00390 { 00391 Timer t; 00392 uint32_t timeout_queue; 00393 int time_spent; 00394 osEvent evt; 00395 00396 timeout_queue = (timeout != 0) ? timeout : osWaitForever /*block indefinitely*/; 00397 00398 t.start(); 00399 evt = ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->get(timeout_queue); 00400 if(evt.status != osEventMessage) 00401 { 00402 return SYS_ARCH_TIMEOUT; 00403 } 00404 time_spent = t.read_ms(); 00405 if(msg!=NULL) 00406 { 00407 *msg = evt.value.p; 00408 } 00409 else 00410 { 00411 ERR("Dropped"); 00412 Thread::wait(100); 00413 } 00414 return time_spent; 00415 } 00416 00417 /* 00418 This is similar to sys_arch_mbox_fetch, however if a message is not 00419 present in the mailbox, it immediately returns with the code 00420 SYS_MBOX_EMPTY. On success 0 is returned with msg pointing to the 00421 message retrieved from the mailbox. 00422 */ 00423 u32_t sys_arch_mbox_tryfetch(sys_mbox_t* pMbox, void **msg) 00424 { 00425 00426 osEvent evt; 00427 00428 evt = ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->get(0); 00429 if(evt.status != osEventMessage) 00430 { 00431 return SYS_MBOX_EMPTY; 00432 } 00433 if(msg!=NULL) 00434 { 00435 *msg = evt.value.p; 00436 } 00437 else 00438 { 00439 ERR("Dropped"); 00440 Thread::wait(100); 00441 } 00442 00443 return ERR_OK; 00444 } 00445 00446 /* 00447 Tries to post a message to mbox by polling (no timeout). 00448 */ 00449 #define X() do{(*((volatile uint32_t *)0x40024048))=__LINE__;}while(0) 00450 #define D(d) do{(*((volatile uint32_t *)0x4002404C))=d;}while(0) 00451 err_t sys_mbox_trypost(sys_mbox_t* pMbox, void *msg) 00452 { 00453 int ret; 00454 00455 if(msg == NULL) 00456 { 00457 ERR("NULL"); 00458 Thread::wait(100); 00459 } 00460 00461 ret = ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->put(msg,0); 00462 if(ret != osOK) 00463 { 00464 ERR("FULL"); 00465 return ERR_MEM; 00466 } 00467 00468 return ERR_OK; 00469 } 00470 00471 /** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ 00472 int sys_mbox_valid(sys_mbox_t *pMbox) 00473 { 00474 00475 if (pMbox->pQueue != NULL) 00476 { 00477 00478 return (pMbox->valid); 00479 } 00480 00481 return false; 00482 } 00483 00484 /** Set an mbox invalid so that sys_mbox_valid returns 0 */ 00485 void sys_mbox_set_invalid(sys_mbox_t *pMbox) 00486 { 00487 00488 pMbox->valid = false; 00489 00490 } 00491 #else 00492 00493 /** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ 00494 int sys_mbox_valid(sys_mbox_t *pMbox) 00495 { 00496 return (pMbox->valid); 00497 } 00498 00499 /** Set an mbox invalid so that sys_mbox_valid returns 0 */ 00500 void sys_mbox_set_invalid(sys_mbox_t *pMbox) 00501 { 00502 pMbox->valid = false; 00503 } 00504 00505 /*-----------------------------------------------------------------------------------*/ 00506 err_t 00507 sys_mbox_new(sys_mbox_t* mb, int size) 00508 { 00509 LWIP_UNUSED_ARG(size); 00510 00511 mb->first = mb->last = 0; 00512 sys_sem_new(&mb->not_empty, 0); 00513 sys_sem_new(&mb->not_full, 0); 00514 sys_sem_new(&mb->mutex, 1); 00515 mb->wait_send = 0; 00516 mb->valid=true; 00517 00518 return ERR_OK; 00519 } 00520 /*-----------------------------------------------------------------------------------*/ 00521 void 00522 sys_mbox_free(sys_mbox_t* mb) 00523 { 00524 if ((mb != NULL)) { 00525 sys_arch_sem_wait(&mb->mutex, 0); 00526 00527 sys_sem_free(&mb->not_empty); 00528 sys_sem_free(&mb->not_full); 00529 sys_sem_free(&mb->mutex); 00530 //mb->not_empty = mb->not_full = mb->mutex = NULL; 00531 mb->valid=false; 00532 /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */ 00533 } 00534 } 00535 /*-----------------------------------------------------------------------------------*/ 00536 err_t 00537 sys_mbox_trypost(sys_mbox_t* mb, void *msg) 00538 { 00539 u8_t first; 00540 LWIP_ASSERT("invalid mbox", (mb != NULL) ); 00541 00542 sys_arch_sem_wait(&mb->mutex, 0); 00543 00544 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n", 00545 (void *)mb, (void *)msg)); 00546 00547 if ((mb->last + 1) >= (mb->first + SYS_MBOX_SIZE)) { 00548 sys_sem_signal(&mb->mutex); 00549 return ERR_MEM; 00550 } 00551 00552 mb->msgs[mb->last % SYS_MBOX_SIZE] = msg; 00553 00554 if (mb->last == mb->first) { 00555 first = 1; 00556 } else { 00557 first = 0; 00558 } 00559 00560 mb->last++; 00561 00562 if (first) { 00563 sys_sem_signal(&mb->not_empty); 00564 } 00565 00566 sys_sem_signal(&mb->mutex); 00567 00568 return ERR_OK; 00569 } 00570 /*-----------------------------------------------------------------------------------*/ 00571 void 00572 sys_mbox_post(sys_mbox_t* mb, void *msg) 00573 { 00574 u8_t first; 00575 LWIP_ASSERT("invalid mbox", (mb != NULL)); 00576 00577 sys_arch_sem_wait(&mb->mutex, 0); 00578 00579 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mb, (void *)msg)); 00580 00581 while ((mb->last + 1) >= (mb->first + SYS_MBOX_SIZE)) { 00582 mb->wait_send++; 00583 sys_sem_signal(&mb->mutex); 00584 sys_arch_sem_wait(&mb->not_full, 0); 00585 sys_arch_sem_wait(&mb->mutex, 0); 00586 mb->wait_send--; 00587 } 00588 00589 mb->msgs[mb->last % SYS_MBOX_SIZE] = msg; 00590 00591 if (mb->last == mb->first) { 00592 first = 1; 00593 } else { 00594 first = 0; 00595 } 00596 00597 mb->last++; 00598 00599 if (first) { 00600 sys_sem_signal(&mb->not_empty); 00601 } 00602 00603 sys_sem_signal(&mb->mutex); 00604 } 00605 /*-----------------------------------------------------------------------------------*/ 00606 u32_t 00607 sys_arch_mbox_tryfetch(sys_mbox_t* mb, void **msg) 00608 { 00609 LWIP_ASSERT("invalid mbox", (mb != NULL)); 00610 00611 sys_arch_sem_wait(&mb->mutex, 0); 00612 00613 if (mb->first == mb->last) { 00614 sys_sem_signal(&mb->mutex); 00615 return SYS_MBOX_EMPTY; 00616 } 00617 00618 if (msg != NULL) { 00619 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mb, *msg)); 00620 *msg = mb->msgs[mb->first % SYS_MBOX_SIZE]; 00621 } 00622 else{ 00623 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mb)); 00624 } 00625 00626 mb->first++; 00627 00628 if (mb->wait_send) { 00629 sys_sem_signal(&mb->not_full); 00630 } 00631 00632 sys_sem_signal(&mb->mutex); 00633 00634 return 0; 00635 } 00636 /*-----------------------------------------------------------------------------------*/ 00637 u32_t 00638 sys_arch_mbox_fetch(sys_mbox_t* mb, void **msg, u32_t timeout) 00639 { 00640 u32_t time_needed = 0; 00641 LWIP_ASSERT("invalid mbox", (mb != NULL)); 00642 00643 /* The mutex lock is quick so we don't bother with the timeout 00644 stuff here. */ 00645 sys_arch_sem_wait(&mb->mutex, 0); 00646 00647 while (mb->first == mb->last) { 00648 sys_sem_signal(&mb->mutex); 00649 00650 /* We block while waiting for a mail to arrive in the mailbox. We 00651 must be prepared to timeout. */ 00652 if (timeout != 0) { 00653 time_needed = sys_arch_sem_wait(&mb->not_empty, timeout); 00654 00655 if (time_needed == SYS_ARCH_TIMEOUT) { 00656 return SYS_ARCH_TIMEOUT; 00657 } 00658 } else { 00659 sys_arch_sem_wait(&mb->not_empty, 0); 00660 } 00661 sys_arch_sem_wait(&mb->mutex, 0); 00662 } 00663 00664 if (msg != NULL) { 00665 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mb, *msg)); 00666 *msg = mb->msgs[mb->first % SYS_MBOX_SIZE]; 00667 } 00668 else{ 00669 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mb)); 00670 } 00671 00672 mb->first++; 00673 00674 if (mb->wait_send) { 00675 sys_sem_signal(&mb->not_full); 00676 } 00677 00678 sys_sem_signal(&mb->mutex); 00679 00680 return time_needed; 00681 } 00682 00683 #endif 00684 00685 //Threads and timeout lists 00686 00687 /* 00688 The implementation reserves a pool of threads that can be used by 00689 LwIP in order to only use static allocation 00690 */ 00691 00692 //sys_thread_t* lwip_system_threads = NULL; //Linked list of active threads 00693 //struct sys_timeo* lwip_system_timeouts = NULL; // Default timeouts list for lwIP 00694 00695 /* 00696 Instanciates a thread for LwIP: 00697 name is the thread name. thread(arg) is the call made as the thread's 00698 entry point. stacksize is the recommended stack size for this thread. 00699 prio is the priority that lwIP asks for. Stack size(s) and priority(ies) 00700 are defined in lwipopts.h. 00701 */ 00702 00703 struct sys_thread 00704 { 00705 Thread* pTask; 00706 //struct sys_timeo* timeouts; 00707 struct sys_thread* next; 00708 }; 00709 struct sys_thread* lwip_system_threads = NULL; //Linked list of active threads 00710 00711 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn fn, void *arg, int stacksize, int prio) 00712 { 00713 SYS_ARCH_DECL_PROTECT(lev); 00714 SYS_ARCH_PROTECT(lev); //Protect this section 00715 struct sys_thread* pT = new struct sys_thread; 00716 SYS_ARCH_UNPROTECT(lev); 00717 if(pT==NULL) 00718 { 00719 ERR("No mem"); 00720 return; 00721 } 00722 00723 SYS_ARCH_PROTECT(lev); //Protect this section 00724 00725 //Link in list 00726 pT->next = lwip_system_threads; 00727 lwip_system_threads = pT; 00728 00729 00730 SYS_ARCH_UNPROTECT(lev); //Protect this section 00731 00732 DBG("Trying to create new thread of stacksize %d and prio %d", stacksize, prio); 00733 00734 //Must be done at the very end because the task will start immediately 00735 SYS_ARCH_PROTECT(lev); 00736 pT->pTask = new Thread((void (*)(void const *argument))fn, arg, (osPriority)prio /*FIXME*/, stacksize); 00737 SYS_ARCH_UNPROTECT(lev); 00738 00739 DBG("pT->pTask=%p", pT->pTask); 00740 if(pT->pTask == NULL) 00741 { 00742 SYS_ARCH_PROTECT(lev); 00743 00744 //Unlink 00745 if(pT == lwip_system_threads) 00746 { 00747 lwip_system_threads = pT->next; 00748 } 00749 else 00750 { 00751 struct sys_thread* pLT = lwip_system_threads; 00752 while(pLT->next != pT) 00753 { 00754 pLT = pLT->next; 00755 } 00756 pLT->next = pT->next; 00757 } 00758 SYS_ARCH_UNPROTECT(lev); //Release protection 00759 SYS_ARCH_PROTECT(lev); 00760 delete pT; 00761 SYS_ARCH_UNPROTECT(lev); 00762 ERR("No mem"); 00763 return; 00764 } 00765 00766 DBG("Thread OK"); 00767 return; //Return the thread 00768 } 00769 #if 0 00770 struct sys_timeouts *sys_arch_timeouts(void) { 00771 struct sys_timeo* timeouts; 00772 00773 SYS_ARCH_DECL_PROTECT(lev); 00774 00775 timeouts = &lwip_system_timeouts; //If there is no match, just return the system-wide default version 00776 00777 SYS_ARCH_PROTECT(lev); //Protect this section 00778 00779 sys_thread_t pT = lwip_system_threads; 00780 00781 // Search the threads list for the thread that is currently running 00782 for ( ; pT!=NULL; pT=pT->next) 00783 { 00784 if ( Task::isCurrent(pT->pTask) ) 00785 { 00786 timeouts = pT->timeouts; 00787 } 00788 } 00789 00790 SYS_ARCH_UNPROTECT(lev); //Release protection 00791 00792 return timeouts; 00793 } 00794 #endif 00795 /* 00796 Architecture-specific initialization. 00797 */ 00798 static Timer sys_jiffies_timer; 00799 00800 void sys_init(void) 00801 { 00802 sys_jiffies_timer.start(); 00803 } 00804 00805 /* 00806 Used by PPP as a timestamp-ish value. 00807 */ 00808 u32_t sys_jiffies(void) 00809 { 00810 static u32_t jiffies = 0; 00811 jiffies += 1 + sys_jiffies_timer.read_ms()/10; 00812 sys_jiffies_timer.reset(); 00813 00814 return jiffies; 00815 } 00816 00817 /** 00818 * Sleep for some ms. Timeouts are NOT processed while sleeping. 00819 * 00820 * @param ms number of milliseconds to sleep 00821 */ 00822 //Change DG, arch specific 00823 void 00824 sys_msleep(u32_t ms) 00825 { 00826 Thread::wait(ms); 00827 } 00828 00829 } //extern "C"
Generated on Tue Jul 12 2022 15:12:16 by 1.7.2