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
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 */
Generated on Tue Jul 12 2022 13:54:55 by
