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.
Dependencies: DebugLib Socket lwip lwip-sys
Fork of NetworkingCoreLib by
Diff: main/lwip/arch/sys_arch.cpp
- Revision:
- 0:013f5d54248c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main/lwip/arch/sys_arch.cpp Thu May 24 14:49:40 2012 +0000
@@ -0,0 +1,829 @@
+/* sysarch.cpp */
+/*
+Copyright (C) 2012 ARM Limited.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#define __DEBUG__ 0
+#ifndef __MODULE__
+#define __MODULE__ "sys_arch.cpp"
+#endif
+
+extern "C"
+{
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/arch.h"
+#include "cc.h"
+#include "sys_arch.h"
+}
+
+#include "core/fwk.h"
+#include "rtos.h"
+#include "mbed.h" //From mbed library
+
+/*
+From http://lwip.wikia.com/wiki/Porting_for_an_OS:
+
+The sys_arch provides semaphores and mailboxes to lwIP. For the full
+lwIP functionality, multiple threads support can be implemented in the
+sys_arch, but this is not required for the basic lwIP functionality.
+*/
+
+extern "C"
+/*
+The file is .cpp to be able to use the C++ abstraction of Mutexes, Semaphores, etc.
+however it should be linked in a C-fashion
+*/
+{
+
+#if SYS_LIGHTWEIGHT_PROT == 0
+#error "SYS_LIGHTWEIGHT_PROT must be set"
+#endif
+
+#if SYS_LIGHTWEIGHT_PROT
+//Critical regions protection
+static Mutex sys_arch_protect_mtx;
+
+sys_prot_t sys_arch_protect(void)
+{
+
+ sys_arch_protect_mtx.lock();
+
+ return 0;
+}
+
+void sys_arch_unprotect(sys_prot_t pval)
+{
+
+ LWIP_UNUSED_ARG(pval);
+ sys_arch_protect_mtx.unlock();
+
+}
+#endif
+
+//Mutexes
+
+/** Create a new mutex
+ * @param mutex pointer to the mutex to create
+ * @return a new mutex */
+err_t sys_mutex_new(sys_mutex_t *pMtx)
+{
+
+ SYS_ARCH_DECL_PROTECT(lev);
+ DBG("Trying to create new mutex");
+
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ pMtx->pMtx = new Mutex();
+ SYS_ARCH_UNPROTECT(lev);
+
+ if(pMtx->pMtx == NULL)
+ {
+ DBG("No mem");
+
+ return ERR_MEM;
+ }
+
+ pMtx->valid = true;
+
+ DBG("mutex created OK");
+
+ return ERR_OK; //Return the semaphore
+}
+
+/** Lock a mutex
+ * @param mutex the mutex to lock */
+void sys_mutex_lock(sys_mutex_t *pMtx)
+{
+
+ ((Mutex*)(pMtx->pMtx))->lock();
+
+}
+
+/** Unlock a mutex
+ * @param mutex the mutex to unlock */
+void sys_mutex_unlock(sys_mutex_t *pMtx)
+{
+
+ ((Mutex*)(pMtx->pMtx))->unlock();
+
+}
+
+/** Delete a mutex
+ * @param mutex the mutex to delete */
+void sys_mutex_free(sys_mutex_t *pMtx)
+{
+
+ SYS_ARCH_DECL_PROTECT(lev);
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ delete ((Mutex*)(pMtx->pMtx));
+ SYS_ARCH_UNPROTECT(lev);
+
+}
+
+/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_mutex_valid(sys_mutex_t *pMtx)
+{
+
+ if (pMtx->pMtx != NULL)
+ {
+
+ return pMtx->valid;
+ }
+
+ return false;
+}
+
+/** Set a mutex invalid so that sys_mutex_valid returns 0 */
+void sys_mutex_set_invalid(sys_mutex_t *pMtx)
+{
+
+ pMtx->valid = false;
+
+}
+
+//Semaphores
+
+/*
+The implementation reserves a pool of semaphores that can be used by
+LwIP in order to only use static allocation
+*/
+
+//static sys_sem sys_sem_pool[LWIP_SEMAPHORES_COUNT] = { 0 };
+
+/*
+Creates and returns a new semaphore. The count argument specifies the
+initial state of the semaphore. Returns the semaphore, or SYS_SEM_NULL
+on error.
+*/
+err_t sys_sem_new_mul(sys_sem_t *pSem, u8_t size, u8_t count)
+{
+
+ SYS_ARCH_DECL_PROTECT(lev);
+ DBG("Trying to create new semaphore of size=%d", size);
+
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ pSem->pSphre = new Semaphore(size);
+ SYS_ARCH_UNPROTECT(lev);
+ if(pSem->pSphre == NULL)
+ {
+ ERR("Failed!");
+ return ERR_MEM;
+ }
+
+ while(count < size)
+ {
+ ((Semaphore*)(pSem->pSphre))->wait();
+ count++;
+ }
+ pSem->valid = true;
+
+
+ return ERR_OK; //Return the semaphore
+}
+
+
+/*
+Creates and returns a new semaphore. The count argument specifies the
+initial state of the semaphore. Returns the semaphore, or SYS_SEM_NULL
+on error.
+*/
+err_t sys_sem_new(sys_sem_t *pSem, u8_t count)
+{
+
+ SYS_ARCH_DECL_PROTECT(lev);
+ DBG("Trying to create new semaphore of count=%d", count);
+
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ pSem->pSphre = new Semaphore(1);
+ SYS_ARCH_UNPROTECT(lev);
+ if(pSem->pSphre == NULL)
+ {
+ ERR("Failed!");
+ return ERR_MEM;
+ }
+
+ if(!count)
+ {
+ ((Semaphore*)(pSem->pSphre))->wait();
+ }
+ pSem->valid = true;
+
+
+ return ERR_OK; //Return the semaphore
+}
+
+/*
+Frees a semaphore created by sys_sem_new. Since these two functions
+provide the entry and exit point for all semaphores used by lwIP, you
+have great flexibility in how these are allocated and deallocated (for
+example, from the heap, a memory pool, a semaphore pool, etc).
+*/
+void sys_sem_free(sys_sem_t *pSem)
+{
+ SYS_ARCH_DECL_PROTECT(lev);
+ DBG("Deleting semaphore");
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ delete ((Semaphore*)(pSem->pSphre));
+ SYS_ARCH_UNPROTECT(lev);
+
+}
+
+/*
+Signals (or releases) a semaphore.
+*/
+void sys_sem_signal(sys_sem_t* pSem)
+{
+
+ ((Semaphore*)(pSem->pSphre))->release(); //Produce (i.e. release) a resource
+
+}
+
+/*
+Blocks the thread while waiting for the semaphore to be signaled. The
+timeout parameter specifies how many milliseconds the function should
+block before returning; if the function times out, it should return
+SYS_ARCH_TIMEOUT. If timeout=0, then the function should block
+indefinitely. If the function acquires the semaphore, it should return
+how many milliseconds expired while waiting for the semaphore. The
+function may return 0 if the semaphore was immediately available.
+*/
+u32_t sys_arch_sem_wait(sys_sem_t* pSem, u32_t timeout)
+{
+
+ int ret;
+ Timer t;
+ uint32_t timeout_sphre;
+ int time_spent;
+
+ timeout_sphre = (timeout != 0) ? timeout : osWaitForever /*block indefinitely*/;
+
+ t.start();
+ ret = ((Semaphore*)(pSem->pSphre))->wait(timeout_sphre);
+ if(ret == 0)
+ {
+
+ return SYS_ARCH_TIMEOUT;
+ }
+ time_spent = t.read_ms();
+
+ return time_spent;
+}
+
+/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_sem_valid(sys_sem_t *pSem)
+{
+
+ if (pSem->pSphre != NULL)
+ {
+
+ return (pSem->valid);
+ }
+
+ return false;
+}
+
+/** Set a semaphore invalid so that sys_sem_valid returns 0 */
+void sys_sem_set_invalid(sys_sem_t *pSem)
+{
+
+ pSem->valid = false;
+
+}
+
+//Mailboxes
+
+/*
+The implementation reserves a pool of mailboxes of generic (void*) type that can be used by
+LwIP in order to only use static allocation
+*/
+
+#define QUEUE_SIZE 8
+#define SYS_MBOX_SIZE QUEUE_SIZE
+#if 0
+/*
+Returns a new mailbox, or SYS_MBOX_NULL on error.
+*/
+err_t sys_mbox_new(sys_mbox_t *pMbox, int size)
+{
+
+ SYS_ARCH_DECL_PROTECT(lev);
+ ERR("Trying to create new queue of size %d", size);
+
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ if(size > QUEUE_SIZE)
+ {
+ ERR("Queue size > QUEUE_SIZE");
+ }
+ pMbox->pQueue = new Queue<void,QUEUE_SIZE>();
+ SYS_ARCH_UNPROTECT(lev);
+ if(pMbox->pQueue == NULL)
+ {
+
+ return ERR_MEM;
+ }
+ pMbox->valid = true;
+
+
+ return ERR_OK; //Return the mailbox
+}
+
+/*
+Deallocates a mailbox. If there are messages still present in the
+mailbox when the mailbox is deallocated, it is an indication of a
+programming error in lwIP and the developer should be notified.
+*/
+void sys_mbox_free(sys_mbox_t* pMbox)
+{
+ ERR("WHY??");
+
+ SYS_ARCH_DECL_PROTECT(lev);
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ delete ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue));
+ SYS_ARCH_UNPROTECT(lev);
+
+}
+
+/*
+Posts the "msg" to the mailbox.
+*/
+void sys_mbox_post(sys_mbox_t* pMbox, void *msg)
+{
+
+ if(msg == NULL)
+ {
+ ERR("NULL");
+ Thread::wait(100);
+ }
+
+ ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->put(msg, osWaitForever);
+
+}
+
+/*
+Blocks the thread until a message arrives in the mailbox, but does not
+block the thread longer than timeout milliseconds (similar to the
+sys_arch_sem_wait() function). The msg argument is a pointer to the
+message in the mailbox and may be NULL to indicate that the message
+should be dropped. This should return either SYS_ARCH_TIMEOUT or the
+number of milliseconds elapsed waiting for a message.
+*/
+u32_t sys_arch_mbox_fetch(sys_mbox_t* pMbox, void **msg, u32_t timeout)
+{
+ Timer t;
+ uint32_t timeout_queue;
+ int time_spent;
+ osEvent evt;
+
+ timeout_queue = (timeout != 0) ? timeout : osWaitForever /*block indefinitely*/;
+
+ t.start();
+ evt = ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->get(timeout_queue);
+ if(evt.status != osEventMessage)
+ {
+ return SYS_ARCH_TIMEOUT;
+ }
+ time_spent = t.read_ms();
+ if(msg!=NULL)
+ {
+ *msg = evt.value.p;
+ }
+ else
+ {
+ ERR("Dropped");
+ Thread::wait(100);
+ }
+ return time_spent;
+}
+
+/*
+This is similar to sys_arch_mbox_fetch, however if a message is not
+present in the mailbox, it immediately returns with the code
+SYS_MBOX_EMPTY. On success 0 is returned with msg pointing to the
+message retrieved from the mailbox.
+*/
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t* pMbox, void **msg)
+{
+
+ osEvent evt;
+
+ evt = ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->get(0);
+ if(evt.status != osEventMessage)
+ {
+ return SYS_MBOX_EMPTY;
+ }
+ if(msg!=NULL)
+ {
+ *msg = evt.value.p;
+ }
+ else
+ {
+ ERR("Dropped");
+ Thread::wait(100);
+ }
+
+ return ERR_OK;
+}
+
+/*
+Tries to post a message to mbox by polling (no timeout).
+*/
+#define X() do{(*((volatile uint32_t *)0x40024048))=__LINE__;}while(0)
+#define D(d) do{(*((volatile uint32_t *)0x4002404C))=d;}while(0)
+err_t sys_mbox_trypost(sys_mbox_t* pMbox, void *msg)
+{
+ int ret;
+
+ if(msg == NULL)
+ {
+ ERR("NULL");
+ Thread::wait(100);
+ }
+
+ ret = ((Queue<void,QUEUE_SIZE>*)(pMbox->pQueue))->put(msg,0);
+ if(ret != osOK)
+ {
+ ERR("FULL");
+ return ERR_MEM;
+ }
+
+ return ERR_OK;
+}
+
+/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_mbox_valid(sys_mbox_t *pMbox)
+{
+
+ if (pMbox->pQueue != NULL)
+ {
+
+ return (pMbox->valid);
+ }
+
+ return false;
+}
+
+/** Set an mbox invalid so that sys_mbox_valid returns 0 */
+void sys_mbox_set_invalid(sys_mbox_t *pMbox)
+{
+
+ pMbox->valid = false;
+
+}
+#else
+
+/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_mbox_valid(sys_mbox_t *pMbox)
+{
+ return (pMbox->valid);
+}
+
+/** Set an mbox invalid so that sys_mbox_valid returns 0 */
+void sys_mbox_set_invalid(sys_mbox_t *pMbox)
+{
+ pMbox->valid = false;
+}
+
+/*-----------------------------------------------------------------------------------*/
+err_t
+sys_mbox_new(sys_mbox_t* mb, int size)
+{
+ LWIP_UNUSED_ARG(size);
+
+ mb->first = mb->last = 0;
+ sys_sem_new(&mb->not_empty, 0);
+ sys_sem_new(&mb->not_full, 0);
+ sys_sem_new(&mb->mutex, 1);
+ mb->wait_send = 0;
+ mb->valid=true;
+
+ return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_free(sys_mbox_t* mb)
+{
+ if ((mb != NULL)) {
+ sys_arch_sem_wait(&mb->mutex, 0);
+
+ sys_sem_free(&mb->not_empty);
+ sys_sem_free(&mb->not_full);
+ sys_sem_free(&mb->mutex);
+ //mb->not_empty = mb->not_full = mb->mutex = NULL;
+ mb->valid=false;
+ /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+err_t
+sys_mbox_trypost(sys_mbox_t* mb, void *msg)
+{
+ u8_t first;
+ LWIP_ASSERT("invalid mbox", (mb != NULL) );
+
+ sys_arch_sem_wait(&mb->mutex, 0);
+
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
+ (void *)mb, (void *)msg));
+
+ if ((mb->last + 1) >= (mb->first + SYS_MBOX_SIZE)) {
+ sys_sem_signal(&mb->mutex);
+ return ERR_MEM;
+ }
+
+ mb->msgs[mb->last % SYS_MBOX_SIZE] = msg;
+
+ if (mb->last == mb->first) {
+ first = 1;
+ } else {
+ first = 0;
+ }
+
+ mb->last++;
+
+ if (first) {
+ sys_sem_signal(&mb->not_empty);
+ }
+
+ sys_sem_signal(&mb->mutex);
+
+ return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_post(sys_mbox_t* mb, void *msg)
+{
+ u8_t first;
+ LWIP_ASSERT("invalid mbox", (mb != NULL));
+
+ sys_arch_sem_wait(&mb->mutex, 0);
+
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mb, (void *)msg));
+
+ while ((mb->last + 1) >= (mb->first + SYS_MBOX_SIZE)) {
+ mb->wait_send++;
+ sys_sem_signal(&mb->mutex);
+ sys_arch_sem_wait(&mb->not_full, 0);
+ sys_arch_sem_wait(&mb->mutex, 0);
+ mb->wait_send--;
+ }
+
+ mb->msgs[mb->last % SYS_MBOX_SIZE] = msg;
+
+ if (mb->last == mb->first) {
+ first = 1;
+ } else {
+ first = 0;
+ }
+
+ mb->last++;
+
+ if (first) {
+ sys_sem_signal(&mb->not_empty);
+ }
+
+ sys_sem_signal(&mb->mutex);
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_mbox_tryfetch(sys_mbox_t* mb, void **msg)
+{
+ LWIP_ASSERT("invalid mbox", (mb != NULL));
+
+ sys_arch_sem_wait(&mb->mutex, 0);
+
+ if (mb->first == mb->last) {
+ sys_sem_signal(&mb->mutex);
+ return SYS_MBOX_EMPTY;
+ }
+
+ if (msg != NULL) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mb, *msg));
+ *msg = mb->msgs[mb->first % SYS_MBOX_SIZE];
+ }
+ else{
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mb));
+ }
+
+ mb->first++;
+
+ if (mb->wait_send) {
+ sys_sem_signal(&mb->not_full);
+ }
+
+ sys_sem_signal(&mb->mutex);
+
+ return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_mbox_fetch(sys_mbox_t* mb, void **msg, u32_t timeout)
+{
+ u32_t time_needed = 0;
+ LWIP_ASSERT("invalid mbox", (mb != NULL));
+
+ /* The mutex lock is quick so we don't bother with the timeout
+ stuff here. */
+ sys_arch_sem_wait(&mb->mutex, 0);
+
+ while (mb->first == mb->last) {
+ sys_sem_signal(&mb->mutex);
+
+ /* We block while waiting for a mail to arrive in the mailbox. We
+ must be prepared to timeout. */
+ if (timeout != 0) {
+ time_needed = sys_arch_sem_wait(&mb->not_empty, timeout);
+
+ if (time_needed == SYS_ARCH_TIMEOUT) {
+ return SYS_ARCH_TIMEOUT;
+ }
+ } else {
+ sys_arch_sem_wait(&mb->not_empty, 0);
+ }
+ sys_arch_sem_wait(&mb->mutex, 0);
+ }
+
+ if (msg != NULL) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mb, *msg));
+ *msg = mb->msgs[mb->first % SYS_MBOX_SIZE];
+ }
+ else{
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mb));
+ }
+
+ mb->first++;
+
+ if (mb->wait_send) {
+ sys_sem_signal(&mb->not_full);
+ }
+
+ sys_sem_signal(&mb->mutex);
+
+ return time_needed;
+}
+
+#endif
+
+//Threads and timeout lists
+
+/*
+The implementation reserves a pool of threads that can be used by
+LwIP in order to only use static allocation
+*/
+
+//sys_thread_t* lwip_system_threads = NULL; //Linked list of active threads
+//struct sys_timeo* lwip_system_timeouts = NULL; // Default timeouts list for lwIP
+
+/*
+Instanciates a thread for LwIP:
+name is the thread name. thread(arg) is the call made as the thread's
+entry point. stacksize is the recommended stack size for this thread.
+prio is the priority that lwIP asks for. Stack size(s) and priority(ies)
+are defined in lwipopts.h.
+*/
+
+struct sys_thread
+{
+ Thread* pTask;
+ //struct sys_timeo* timeouts;
+ struct sys_thread* next;
+};
+struct sys_thread* lwip_system_threads = NULL; //Linked list of active threads
+
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn fn, void *arg, int stacksize, int prio)
+{
+ SYS_ARCH_DECL_PROTECT(lev);
+ SYS_ARCH_PROTECT(lev); //Protect this section
+ struct sys_thread* pT = new struct sys_thread;
+ SYS_ARCH_UNPROTECT(lev);
+ if(pT==NULL)
+ {
+ ERR("No mem");
+ return;
+ }
+
+ SYS_ARCH_PROTECT(lev); //Protect this section
+
+ //Link in list
+ pT->next = lwip_system_threads;
+ lwip_system_threads = pT;
+
+
+ SYS_ARCH_UNPROTECT(lev); //Protect this section
+
+ DBG("Trying to create new thread of stacksize %d and prio %d", stacksize, prio);
+
+ //Must be done at the very end because the task will start immediately
+ SYS_ARCH_PROTECT(lev);
+ pT->pTask = new Thread((void (*)(void const *argument))fn, arg, (osPriority)prio /*FIXME*/, stacksize);
+ SYS_ARCH_UNPROTECT(lev);
+
+ DBG("pT->pTask=%p", pT->pTask);
+ if(pT->pTask == NULL)
+ {
+ SYS_ARCH_PROTECT(lev);
+
+ //Unlink
+ if(pT == lwip_system_threads)
+ {
+ lwip_system_threads = pT->next;
+ }
+ else
+ {
+ struct sys_thread* pLT = lwip_system_threads;
+ while(pLT->next != pT)
+ {
+ pLT = pLT->next;
+ }
+ pLT->next = pT->next;
+ }
+ SYS_ARCH_UNPROTECT(lev); //Release protection
+ SYS_ARCH_PROTECT(lev);
+ delete pT;
+ SYS_ARCH_UNPROTECT(lev);
+ ERR("No mem");
+ return;
+ }
+
+ DBG("Thread OK");
+ return; //Return the thread
+}
+#if 0
+struct sys_timeouts *sys_arch_timeouts(void) {
+ struct sys_timeo* timeouts;
+
+ SYS_ARCH_DECL_PROTECT(lev);
+
+ timeouts = &lwip_system_timeouts; //If there is no match, just return the system-wide default version
+
+ SYS_ARCH_PROTECT(lev); //Protect this section
+
+ sys_thread_t pT = lwip_system_threads;
+
+ // Search the threads list for the thread that is currently running
+ for ( ; pT!=NULL; pT=pT->next)
+ {
+ if ( Task::isCurrent(pT->pTask) )
+ {
+ timeouts = pT->timeouts;
+ }
+ }
+
+ SYS_ARCH_UNPROTECT(lev); //Release protection
+
+ return timeouts;
+}
+#endif
+/*
+Architecture-specific initialization.
+*/
+static Timer sys_jiffies_timer;
+
+void sys_init(void)
+{
+ sys_jiffies_timer.start();
+}
+
+/*
+Used by PPP as a timestamp-ish value.
+*/
+u32_t sys_jiffies(void)
+{
+ static u32_t jiffies = 0;
+ jiffies += 1 + sys_jiffies_timer.read_ms()/10;
+ sys_jiffies_timer.reset();
+
+ return jiffies;
+}
+
+/**
+ * Sleep for some ms. Timeouts are NOT processed while sleeping.
+ *
+ * @param ms number of milliseconds to sleep
+ */
+//Change DG, arch specific
+void
+sys_msleep(u32_t ms)
+{
+ Thread::wait(ms);
+}
+
+} //extern "C"
