Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sys_arch.c Source File

sys_arch.c

00001 /*
00002  * Copyright (c) 2017 Simon Goldschmidt
00003  * All rights reserved. 
00004  * 
00005  * Redistribution and use in source and binary forms, with or without modification, 
00006  * are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  *    this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright notice,
00011  *    this list of conditions and the following disclaimer in the documentation
00012  *    and/or other materials provided with the distribution.
00013  * 3. The name of the author may not be used to endorse or promote products
00014  *    derived from this software without specific prior written permission. 
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00017  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00018  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00019  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00020  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00021  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00024  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00025  * OF SUCH DAMAGE.
00026  *
00027  * This file is part of the lwIP TCP/IP stack.
00028  * 
00029  * Author: Simon Goldschmidt
00030  *
00031  */
00032 
00033 
00034 #include <lwip/opt.h>
00035 #include <lwip/arch.h>
00036 #if !NO_SYS
00037 #include "sys_arch.h"
00038 #endif
00039 #include <lwip/stats.h>
00040 #include <lwip/debug.h>
00041 #include <lwip/sys.h>
00042 
00043 #include <string.h>
00044 
00045 u32_t lwip_sys_now;
00046 
00047 u32_t
00048 sys_jiffies(void)
00049 {
00050   return lwip_sys_now;
00051 }
00052 
00053 u32_t
00054 sys_now(void)
00055 {
00056   return lwip_sys_now;
00057 }
00058 
00059 void
00060 sys_init(void)
00061 {
00062 }
00063 
00064 #if !NO_SYS
00065 
00066 test_sys_arch_waiting_fn the_waiting_fn;
00067 
00068 void
00069 test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn)
00070 {
00071   the_waiting_fn = waiting_fn;
00072 }
00073 
00074 err_t
00075 sys_sem_new(sys_sem_t *sem, u8_t count)
00076 {
00077   LWIP_ASSERT("sem != NULL", sem != NULL);
00078   *sem = count + 1;
00079   return ERR_OK;
00080 }
00081 
00082 void
00083 sys_sem_free(sys_sem_t *sem)
00084 {
00085   LWIP_ASSERT("sem != NULL", sem != NULL);
00086   *sem = 0;
00087 }
00088 
00089 void
00090 sys_sem_set_invalid(sys_sem_t *sem)
00091 {
00092   LWIP_ASSERT("sem != NULL", sem != NULL);
00093   *sem = 0;
00094 }
00095 
00096 /* semaphores are 1-based because RAM is initialized as 0, which would be valid */
00097 u32_t
00098 sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
00099 {
00100   u32_t ret = 0;
00101   LWIP_ASSERT("sem != NULL", sem != NULL);
00102   LWIP_ASSERT("*sem > 0", *sem > 0);
00103   if (*sem == 1) {
00104     /* need to wait */
00105     if(!timeout)
00106     {
00107       /* wait infinite */
00108       LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
00109       do {
00110         int expectSomething = the_waiting_fn(sem, NULL);
00111         LWIP_ASSERT("*sem > 0", *sem > 0);
00112         LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
00113         ret++;
00114         if (ret == SYS_ARCH_TIMEOUT) {
00115           ret--;
00116         }
00117       } while(*sem == 1);
00118     }
00119     else
00120     {
00121       if (the_waiting_fn) {
00122         int expectSomething = the_waiting_fn(sem, NULL);
00123         LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
00124       }
00125       LWIP_ASSERT("*sem > 0", *sem > 0);
00126       if (*sem == 1) {
00127         return SYS_ARCH_TIMEOUT;
00128       }
00129       ret = 1;
00130     }
00131   }
00132   LWIP_ASSERT("*sem > 0", *sem > 0);
00133   (*sem)--;
00134   LWIP_ASSERT("*sem > 0", *sem > 0);
00135   /* return the time we waited for the sem */
00136   return ret;
00137 }
00138 
00139 void
00140 sys_sem_signal(sys_sem_t *sem)
00141 {
00142   LWIP_ASSERT("sem != NULL", sem != NULL);
00143   LWIP_ASSERT("*sem > 0", *sem > 0);
00144   (*sem)++;
00145   LWIP_ASSERT("*sem > 0", *sem > 0);
00146 }
00147 
00148 err_t
00149 sys_mutex_new(sys_mutex_t *mutex)
00150 {
00151   LWIP_ASSERT("mutex != NULL", mutex != NULL);
00152   *mutex = 1; /* 1 allocated */
00153   return ERR_OK;
00154 }
00155 
00156 void
00157 sys_mutex_free(sys_mutex_t *mutex)
00158 {
00159   /* parameter check */
00160   LWIP_ASSERT("mutex != NULL", mutex != NULL);
00161   LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
00162   *mutex = 0;
00163 }
00164 
00165 void
00166 sys_mutex_set_invalid(sys_mutex_t *mutex)
00167 {
00168   LWIP_ASSERT("mutex != NULL", mutex != NULL);
00169   *mutex = 0;
00170 }
00171 
00172 void
00173 sys_mutex_lock(sys_mutex_t *mutex)
00174 {
00175   /* nothing to do, no multithreading supported */
00176   LWIP_ASSERT("mutex != NULL", mutex != NULL);
00177   /* check that the mutext is valid and unlocked (no nested locking) */
00178   LWIP_ASSERT("*mutex >= 1", *mutex == 1);
00179   /* we count up just to check the correct pairing of lock/unlock */
00180   (*mutex)++;
00181   LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
00182 }
00183 
00184 void
00185 sys_mutex_unlock(sys_mutex_t *mutex)
00186 {
00187   /* nothing to do, no multithreading supported */
00188   LWIP_ASSERT("mutex != NULL", mutex != NULL);
00189   LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
00190   /* we count down just to check the correct pairing of lock/unlock */
00191   (*mutex)--;
00192   LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
00193 }
00194 
00195 
00196 sys_thread_t
00197 sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
00198 {
00199   LWIP_UNUSED_ARG(name);
00200   LWIP_UNUSED_ARG(function);
00201   LWIP_UNUSED_ARG(arg);
00202   LWIP_UNUSED_ARG(stacksize);
00203   LWIP_UNUSED_ARG(prio);
00204   /* threads not supported */
00205   return 0;
00206 }
00207 
00208 err_t
00209 sys_mbox_new(sys_mbox_t *mbox, int size)
00210 {
00211   int mboxsize = size;
00212   LWIP_ASSERT("mbox != NULL", mbox != NULL);
00213   LWIP_ASSERT("size >= 0", size >= 0);
00214   if (size == 0) {
00215     mboxsize = 1024;
00216   }
00217   mbox->head = mbox->tail = 0;
00218   mbox->sem = mbox; /* just point to something for sys_mbox_valid() */
00219   mbox->q_mem = (void**)malloc(sizeof(void*)*mboxsize);
00220   mbox->size = mboxsize;
00221   mbox->used = 0;
00222 
00223   memset(mbox->q_mem, 0, sizeof(void*)*mboxsize);
00224   return ERR_OK;
00225 }
00226 
00227 void
00228 sys_mbox_free(sys_mbox_t *mbox)
00229 {
00230   /* parameter check */
00231   LWIP_ASSERT("mbox != NULL", mbox != NULL);
00232   LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL);
00233   LWIP_ASSERT("mbox->sem == mbox", mbox->sem == mbox);
00234   LWIP_ASSERT("mbox->q_mem != NULL", mbox->q_mem != NULL);
00235   mbox->sem = NULL;
00236   free(mbox->q_mem);
00237   mbox->q_mem = NULL;
00238 }
00239 
00240 void
00241 sys_mbox_set_invalid(sys_mbox_t *mbox)
00242 {
00243   LWIP_ASSERT("mbox != NULL", mbox != NULL);
00244   LWIP_ASSERT("mbox->q_mem == NULL", mbox->q_mem == NULL);
00245   mbox->sem = NULL;
00246   mbox->q_mem = NULL;
00247 }
00248 
00249 void
00250 sys_mbox_post(sys_mbox_t *q, void *msg)
00251 {
00252   LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
00253   LWIP_ASSERT("q->sem == q", q->sem == q);
00254   LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
00255   LWIP_ASSERT("q->used >= 0", q->used >= 0);
00256   LWIP_ASSERT("q->size > 0", q->size > 0);
00257 
00258   LWIP_ASSERT("mbox already full", q->used < q->size);
00259 
00260   q->q_mem[q->head] = msg;
00261   q->head++;
00262   if (q->head >= (unsigned int)q->size) {
00263     q->head = 0;
00264   }
00265   LWIP_ASSERT("mbox is full!", q->head != q->tail);
00266   q->used++;
00267 }
00268 
00269 err_t
00270 sys_mbox_trypost(sys_mbox_t *q, void *msg)
00271 {
00272   LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
00273   LWIP_ASSERT("q->sem == q", q->sem == q);
00274   LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
00275   LWIP_ASSERT("q->used >= 0", q->used >= 0);
00276   LWIP_ASSERT("q->size > 0", q->size > 0);
00277   LWIP_ASSERT("q->used <= q->size", q->used <= q->size);
00278 
00279   if (q->used == q->size) {
00280     return ERR_MEM;
00281   }
00282   sys_mbox_post(q, msg);
00283   return ERR_OK;
00284 }
00285 
00286 err_t
00287 sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
00288 {
00289   return sys_mbox_trypost(q, msg);
00290 }
00291 
00292 u32_t
00293 sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout)
00294 {
00295   u32_t ret = 0;
00296   u32_t ret2;
00297   LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
00298   LWIP_ASSERT("q->sem == q", q->sem == q);
00299   LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
00300   LWIP_ASSERT("q->used >= 0", q->used >= 0);
00301   LWIP_ASSERT("q->size > 0", q->size > 0);
00302 
00303   if (q->used == 0) {
00304     /* need to wait */
00305     /* need to wait */
00306     if(!timeout)
00307     {
00308       /* wait infinite */
00309       LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
00310       do {
00311         int expectSomething = the_waiting_fn(NULL, q);
00312         LWIP_ASSERT("q->used >= 0", q->used >= 0);
00313         LWIP_ASSERT("expecting item available but it's 0", !expectSomething || (q->used > 0));
00314         ret++;
00315         if (ret == SYS_ARCH_TIMEOUT) {
00316           ret--;
00317         }
00318       } while(q->used == 0);
00319     }
00320     else
00321     {
00322       if (the_waiting_fn) {
00323         int expectSomething = the_waiting_fn(NULL, q);
00324         LWIP_ASSERT("expecting item available count but it's 0", !expectSomething || (q->used > 0));
00325       }
00326       LWIP_ASSERT("q->used >= 0", q->used >= 0);
00327       if (q->used == 0) {
00328         if(msg) {
00329           *msg = NULL;
00330         }
00331         return SYS_ARCH_TIMEOUT;
00332       }
00333       ret = 1;
00334     }
00335   }
00336   LWIP_ASSERT("q->used > 0", q->used > 0);
00337   ret2 = sys_arch_mbox_tryfetch(q, msg);
00338   LWIP_ASSERT("got no message", ret2 == 0);
00339   return ret;
00340 }
00341 
00342 u32_t
00343 sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
00344 {
00345   LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
00346   LWIP_ASSERT("q->sem == q", q->sem == q);
00347   LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
00348   LWIP_ASSERT("q->used >= 0", q->used >= 0);
00349   LWIP_ASSERT("q->size > 0", q->size > 0);
00350 
00351   if (!q->used) {
00352     return SYS_ARCH_TIMEOUT;
00353   }
00354   if(msg) {
00355     *msg = q->q_mem[q->tail];
00356   }
00357 
00358   q->tail++;
00359   if (q->tail >= (unsigned int)q->size) {
00360     q->tail = 0;
00361   }
00362   q->used--;
00363   LWIP_ASSERT("q->used >= 0", q->used >= 0);
00364   return 0;
00365 }
00366 
00367 #if LWIP_NETCONN_SEM_PER_THREAD
00368 #error LWIP_NETCONN_SEM_PER_THREAD==1 not supported
00369 #endif /* LWIP_NETCONN_SEM_PER_THREAD */
00370 
00371 #endif /* !NO_SYS */