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.
sys.h
00001 /** 00002 * @file 00003 * OS abstraction layer 00004 */ 00005 00006 /* 00007 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00008 * All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without modification, 00011 * are permitted provided that the following conditions are met: 00012 * 00013 * 1. Redistributions of source code must retain the above copyright notice, 00014 * this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright notice, 00016 * this list of conditions and the following disclaimer in the documentation 00017 * and/or other materials provided with the distribution. 00018 * 3. The name of the author may not be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00022 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00024 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00026 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00029 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00030 * OF SUCH DAMAGE. 00031 * 00032 * This file is part of the lwIP TCP/IP stack. 00033 * 00034 * Author: Adam Dunkels <adam@sics.se> 00035 */ 00036 00037 #ifndef LWIP_HDR_SYS_H 00038 #define LWIP_HDR_SYS_H 00039 00040 #include "lwip/opt.h" 00041 00042 #ifdef __cplusplus 00043 extern "C" { 00044 #endif 00045 00046 #if NO_SYS 00047 00048 /* For a totally minimal and standalone system, we provide null 00049 definitions of the sys_ functions. */ 00050 typedef u8_t sys_sem_t; 00051 typedef u8_t sys_mutex_t; 00052 typedef u8_t sys_mbox_t; 00053 00054 #define sys_sem_new(s, c) ERR_OK 00055 #define sys_sem_signal(s) 00056 #define sys_sem_wait(s) 00057 #define sys_arch_sem_wait(s,t) 00058 #define sys_sem_free(s) 00059 #define sys_sem_valid(s) 0 00060 #define sys_sem_valid_val(s) 0 00061 #define sys_sem_set_invalid(s) 00062 #define sys_sem_set_invalid_val(s) 00063 #define sys_mutex_new(mu) ERR_OK 00064 #define sys_mutex_lock(mu) 00065 #define sys_mutex_unlock(mu) 00066 #define sys_mutex_free(mu) 00067 #define sys_mutex_valid(mu) 0 00068 #define sys_mutex_set_invalid(mu) 00069 #define sys_mbox_new(m, s) ERR_OK 00070 #define sys_mbox_fetch(m,d) 00071 #define sys_mbox_tryfetch(m,d) 00072 #define sys_mbox_post(m,d) 00073 #define sys_mbox_trypost(m,d) 00074 #define sys_mbox_free(m) 00075 #define sys_mbox_valid(m) 00076 #define sys_mbox_valid_val(m) 00077 #define sys_mbox_set_invalid(m) 00078 #define sys_mbox_set_invalid_val(m) 00079 00080 #define sys_thread_new(n,t,a,s,p) 00081 00082 #define sys_msleep(t) 00083 00084 #else /* NO_SYS */ 00085 00086 /** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ 00087 #define SYS_ARCH_TIMEOUT 0xffffffffUL 00088 00089 /** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. 00090 * For now we use the same magic value, but we allow this to change in future. 00091 */ 00092 #define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT 00093 00094 #include "lwip/err.h" 00095 #include "arch/sys_arch.h" 00096 00097 /** Function prototype for thread functions */ 00098 typedef void (*lwip_thread_fn)(void *arg); 00099 00100 /* Function prototypes for functions to be implemented by platform ports 00101 (in sys_arch.c) */ 00102 00103 /* Mutex functions: */ 00104 00105 /** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores 00106 should be used instead */ 00107 #ifndef LWIP_COMPAT_MUTEX 00108 #define LWIP_COMPAT_MUTEX 0 00109 #endif 00110 00111 #if LWIP_COMPAT_MUTEX 00112 /* for old ports that don't have mutexes: define them to binary semaphores */ 00113 #define sys_mutex_t sys_sem_t 00114 #define sys_mutex_new(mutex) sys_sem_new(mutex, 1) 00115 #define sys_mutex_lock(mutex) sys_sem_wait(mutex) 00116 #define sys_mutex_unlock(mutex) sys_sem_signal(mutex) 00117 #define sys_mutex_free(mutex) sys_sem_free(mutex) 00118 #define sys_mutex_valid(mutex) sys_sem_valid(mutex) 00119 #define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) 00120 00121 #else /* LWIP_COMPAT_MUTEX */ 00122 00123 /** 00124 * @ingroup sys_mutex 00125 * Create a new mutex. 00126 * Note that mutexes are expected to not be taken recursively by the lwIP code, 00127 * so both implementation types (recursive or non-recursive) should work. 00128 * @param mutex pointer to the mutex to create 00129 * @return ERR_OK if successful, another err_t otherwise 00130 */ 00131 err_t sys_mutex_new(sys_mutex_t *mutex); 00132 /** 00133 * @ingroup sys_mutex 00134 * Lock a mutex 00135 * @param mutex the mutex to lock 00136 */ 00137 void sys_mutex_lock(sys_mutex_t *mutex); 00138 /** 00139 * @ingroup sys_mutex 00140 * Unlock a mutex 00141 * @param mutex the mutex to unlock 00142 */ 00143 void sys_mutex_unlock(sys_mutex_t *mutex); 00144 /** 00145 * @ingroup sys_mutex 00146 * Delete a semaphore 00147 * @param mutex the mutex to delete 00148 */ 00149 void sys_mutex_free(sys_mutex_t *mutex); 00150 #ifndef sys_mutex_valid 00151 /** 00152 * @ingroup sys_mutex 00153 * Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid 00154 */ 00155 int sys_mutex_valid(sys_mutex_t *mutex); 00156 #endif 00157 #ifndef sys_mutex_set_invalid 00158 /** 00159 * @ingroup sys_mutex 00160 * Set a mutex invalid so that sys_mutex_valid returns 0 00161 */ 00162 void sys_mutex_set_invalid(sys_mutex_t *mutex); 00163 #endif 00164 #endif /* LWIP_COMPAT_MUTEX */ 00165 00166 /* Semaphore functions: */ 00167 00168 /** 00169 * @ingroup sys_sem 00170 * Create a new semaphore 00171 * @param sem pointer to the semaphore to create 00172 * @param count initial count of the semaphore 00173 * @return ERR_OK if successful, another err_t otherwise 00174 */ 00175 err_t sys_sem_new(sys_sem_t *sem, u8_t count); 00176 /** 00177 * @ingroup sys_sem 00178 * Signals a semaphore 00179 * @param sem the semaphore to signal 00180 */ 00181 void sys_sem_signal(sys_sem_t *sem); 00182 /** 00183 * @ingroup sys_sem 00184 * Wait for a semaphore for the specified timeout 00185 * @param sem the semaphore to wait for 00186 * @param timeout timeout in milliseconds to wait (0 = wait forever) 00187 * @return time (in milliseconds) waited for the semaphore 00188 * or SYS_ARCH_TIMEOUT on timeout 00189 */ 00190 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); 00191 /** 00192 * @ingroup sys_sem 00193 * Delete a semaphore 00194 * @param sem semaphore to delete 00195 */ 00196 void sys_sem_free(sys_sem_t *sem); 00197 /** Wait for a semaphore - forever/no timeout */ 00198 #define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) 00199 #ifndef sys_sem_valid 00200 /** 00201 * @ingroup sys_sem 00202 * Check if a semaphore is valid/allocated: return 1 for valid, 0 for invalid 00203 */ 00204 int sys_sem_valid(sys_sem_t *sem); 00205 #endif 00206 #ifndef sys_sem_set_invalid 00207 /** 00208 * @ingroup sys_sem 00209 * Set a semaphore invalid so that sys_sem_valid returns 0 00210 */ 00211 void sys_sem_set_invalid(sys_sem_t *sem); 00212 #endif 00213 #ifndef sys_sem_valid_val 00214 /** 00215 * Same as sys_sem_valid() but taking a value, not a pointer 00216 */ 00217 #define sys_sem_valid_val(sem) sys_sem_valid(&(sem)) 00218 #endif 00219 #ifndef sys_sem_set_invalid_val 00220 /** 00221 * Same as sys_sem_set_invalid() but taking a value, not a pointer 00222 */ 00223 #define sys_sem_set_invalid_val(sem) sys_sem_set_invalid(&(sem)) 00224 #endif 00225 00226 #ifndef sys_msleep 00227 /** 00228 * @ingroup sys_misc 00229 * Sleep for specified number of ms 00230 */ 00231 void sys_msleep(u32_t ms); /* only has a (close to) 1 ms resolution. */ 00232 #endif 00233 00234 /* Mailbox functions. */ 00235 00236 /** 00237 * @ingroup sys_mbox 00238 * Create a new mbox of specified size 00239 * @param mbox pointer to the mbox to create 00240 * @param size (minimum) number of messages in this mbox 00241 * @return ERR_OK if successful, another err_t otherwise 00242 */ 00243 err_t sys_mbox_new(sys_mbox_t *mbox, int size); 00244 /** 00245 * @ingroup sys_mbox 00246 * Post a message to an mbox - may not fail 00247 * -> blocks if full, only used from tasks not from ISR 00248 * @param mbox mbox to posts the message 00249 * @param msg message to post (ATTENTION: can be NULL) 00250 */ 00251 void sys_mbox_post(sys_mbox_t *mbox, void *msg); 00252 /** 00253 * @ingroup sys_mbox 00254 * Try to post a message to an mbox - may fail if full or ISR 00255 * @param mbox mbox to posts the message 00256 * @param msg message to post (ATTENTION: can be NULL) 00257 */ 00258 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); 00259 /** 00260 * @ingroup sys_mbox 00261 * Wait for a new message to arrive in the mbox 00262 * @param mbox mbox to get a message from 00263 * @param msg pointer where the message is stored 00264 * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) 00265 * @return time (in milliseconds) waited for a message, may be 0 if not waited 00266 or SYS_ARCH_TIMEOUT on timeout 00267 * The returned time has to be accurate to prevent timer jitter! 00268 */ 00269 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); 00270 /* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ 00271 #ifndef sys_arch_mbox_tryfetch 00272 /** 00273 * @ingroup sys_mbox 00274 * Wait for a new message to arrive in the mbox 00275 * @param mbox mbox to get a message from 00276 * @param msg pointer where the message is stored 00277 * @return 0 (milliseconds) if a message has been received 00278 * or SYS_MBOX_EMPTY if the mailbox is empty 00279 */ 00280 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); 00281 #endif 00282 /** 00283 * For now, we map straight to sys_arch implementation. 00284 */ 00285 #define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) 00286 /** 00287 * @ingroup sys_mbox 00288 * Delete an mbox 00289 * @param mbox mbox to delete 00290 */ 00291 void sys_mbox_free(sys_mbox_t *mbox); 00292 #define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) 00293 #ifndef sys_mbox_valid 00294 /** 00295 * @ingroup sys_mbox 00296 * Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid 00297 */ 00298 int sys_mbox_valid(sys_mbox_t *mbox); 00299 #endif 00300 #ifndef sys_mbox_set_invalid 00301 /** 00302 * @ingroup sys_mbox 00303 * Set an mbox invalid so that sys_mbox_valid returns 0 00304 */ 00305 void sys_mbox_set_invalid(sys_mbox_t *mbox); 00306 #endif 00307 #ifndef sys_mbox_valid_val 00308 /** 00309 * Same as sys_mbox_valid() but taking a value, not a pointer 00310 */ 00311 #define sys_mbox_valid_val(mbox) sys_mbox_valid(&(mbox)) 00312 #endif 00313 #ifndef sys_mbox_set_invalid_val 00314 /** 00315 * Same as sys_mbox_set_invalid() but taking a value, not a pointer 00316 */ 00317 #define sys_mbox_set_invalid_val(mbox) sys_mbox_set_invalid(&(mbox)) 00318 #endif 00319 00320 00321 /** 00322 * @ingroup sys_misc 00323 * The only thread function: 00324 * Creates a new thread 00325 * ATTENTION: although this function returns a value, it MUST NOT FAIL (ports have to assert this!) 00326 * @param name human-readable name for the thread (used for debugging purposes) 00327 * @param thread thread-function 00328 * @param arg parameter passed to 'thread' 00329 * @param stacksize stack size in bytes for the new thread (may be ignored by ports) 00330 * @param prio priority of the new thread (may be ignored by ports) */ 00331 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); 00332 00333 #endif /* NO_SYS */ 00334 00335 /* sys_init() must be called before anything else. */ 00336 void sys_init(void); 00337 00338 #ifndef sys_jiffies 00339 /** 00340 * Ticks/jiffies since power up. 00341 */ 00342 u32_t sys_jiffies(void); 00343 #endif 00344 00345 /** 00346 * @ingroup sys_time 00347 * Returns the current time in milliseconds, 00348 * may be the same as sys_jiffies or at least based on it. 00349 */ 00350 u32_t sys_now(void); 00351 00352 /* Critical Region Protection */ 00353 /* These functions must be implemented in the sys_arch.c file. 00354 In some implementations they can provide a more light-weight protection 00355 mechanism than using semaphores. Otherwise semaphores can be used for 00356 implementation */ 00357 #ifndef SYS_ARCH_PROTECT 00358 /** SYS_LIGHTWEIGHT_PROT 00359 * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection 00360 * for certain critical regions during buffer allocation, deallocation and memory 00361 * allocation and deallocation. 00362 */ 00363 #if SYS_LIGHTWEIGHT_PROT 00364 00365 /** 00366 * @ingroup sys_prot 00367 * SYS_ARCH_DECL_PROTECT 00368 * declare a protection variable. This macro will default to defining a variable of 00369 * type sys_prot_t. If a particular port needs a different implementation, then 00370 * this macro may be defined in sys_arch.h. 00371 */ 00372 #define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev 00373 /** 00374 * @ingroup sys_prot 00375 * SYS_ARCH_PROTECT 00376 * Perform a "fast" protect. This could be implemented by 00377 * disabling interrupts for an embedded system or by using a semaphore or 00378 * mutex. The implementation should allow calling SYS_ARCH_PROTECT when 00379 * already protected. The old protection level is returned in the variable 00380 * "lev". This macro will default to calling the sys_arch_protect() function 00381 * which should be implemented in sys_arch.c. If a particular port needs a 00382 * different implementation, then this macro may be defined in sys_arch.h 00383 */ 00384 #define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() 00385 /** 00386 * @ingroup sys_prot 00387 * SYS_ARCH_UNPROTECT 00388 * Perform a "fast" set of the protection level to "lev". This could be 00389 * implemented by setting the interrupt level to "lev" within the MACRO or by 00390 * using a semaphore or mutex. This macro will default to calling the 00391 * sys_arch_unprotect() function which should be implemented in 00392 * sys_arch.c. If a particular port needs a different implementation, then 00393 * this macro may be defined in sys_arch.h 00394 */ 00395 #define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) 00396 sys_prot_t sys_arch_protect(void); 00397 void sys_arch_unprotect(sys_prot_t pval); 00398 00399 #else 00400 00401 #define SYS_ARCH_DECL_PROTECT(lev) 00402 #define SYS_ARCH_PROTECT(lev) 00403 #define SYS_ARCH_UNPROTECT(lev) 00404 00405 #endif /* SYS_LIGHTWEIGHT_PROT */ 00406 00407 #endif /* SYS_ARCH_PROTECT */ 00408 00409 /* 00410 * Macros to set/get and increase/decrease variables in a thread-safe way. 00411 * Use these for accessing variable that are used from more than one thread. 00412 */ 00413 00414 #ifndef SYS_ARCH_INC 00415 #define SYS_ARCH_INC(var, val) do { \ 00416 SYS_ARCH_DECL_PROTECT(old_level); \ 00417 SYS_ARCH_PROTECT(old_level); \ 00418 var += val; \ 00419 SYS_ARCH_UNPROTECT(old_level); \ 00420 } while(0) 00421 #endif /* SYS_ARCH_INC */ 00422 00423 #ifndef SYS_ARCH_DEC 00424 #define SYS_ARCH_DEC(var, val) do { \ 00425 SYS_ARCH_DECL_PROTECT(old_level); \ 00426 SYS_ARCH_PROTECT(old_level); \ 00427 var -= val; \ 00428 SYS_ARCH_UNPROTECT(old_level); \ 00429 } while(0) 00430 #endif /* SYS_ARCH_DEC */ 00431 00432 #ifndef SYS_ARCH_GET 00433 #define SYS_ARCH_GET(var, ret) do { \ 00434 SYS_ARCH_DECL_PROTECT(old_level); \ 00435 SYS_ARCH_PROTECT(old_level); \ 00436 ret = var; \ 00437 SYS_ARCH_UNPROTECT(old_level); \ 00438 } while(0) 00439 #endif /* SYS_ARCH_GET */ 00440 00441 #ifndef SYS_ARCH_SET 00442 #define SYS_ARCH_SET(var, val) do { \ 00443 SYS_ARCH_DECL_PROTECT(old_level); \ 00444 SYS_ARCH_PROTECT(old_level); \ 00445 var = val; \ 00446 SYS_ARCH_UNPROTECT(old_level); \ 00447 } while(0) 00448 #endif /* SYS_ARCH_SET */ 00449 00450 00451 #ifdef __cplusplus 00452 } 00453 #endif 00454 00455 #endif /* LWIP_HDR_SYS_H */
Generated on Tue Jul 12 2022 14:24:39 by
