1 /* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ 2 3 /* 4 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without modification, 8 * are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 * OF SUCH DAMAGE. 28 * 29 * This file is part of the lwIP TCP/IP stack. 30 * 31 * Author: Adam Dunkels <adam@sics.se> 32 * 33 */ 34 #ifndef __LWIP_SYS_H__ 35 #define __LWIP_SYS_H__ 36 37 #include "lwip/opt.h" 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 #if NO_SYS 44 45 /* For a totally minimal and standalone system, we provide null 46 definitions of the sys_ functions. */ 47 typedef u8_t sys_sem_t; 48 typedef u8_t sys_mbox_t; 49 struct sys_timeo {u8_t dummy;}; 50 51 #define sys_init() 52 #define sys_timeout(m,h,a) 53 #define sys_untimeout(m,a) 54 #define sys_sem_new(c) c 55 #define sys_sem_signal(s) 56 #define sys_sem_wait(s) 57 #define sys_sem_wait_timeout(s,t) 58 #define sys_arch_sem_wait(s,t) 59 #define sys_sem_free(s) 60 #define sys_mbox_new(s) 0 61 #define sys_mbox_fetch(m,d) 62 #define sys_mbox_tryfetch(m,d) 63 #define sys_mbox_post(m,d) 64 #define sys_mbox_trypost(m,d) 65 #define sys_mbox_free(m) 66 67 #define sys_thread_new(n,t,a,s,p) 68 69 #else /* NO_SYS */ 70 71 /** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ 72 #define SYS_ARCH_TIMEOUT 0xffffffffUL 73 74 /* sys_mbox_tryfetch returns SYS_MBOX_EMPTY if appropriate. 75 * For now we use the same magic value, but we allow this to change in future. 76 */ 77 #define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT 78 79 #include "lwip/err.h" 80 #include "arch/sys_arch.h" 81 82 typedef void (* sys_timeout_handler)(void *arg); 83 84 struct sys_timeo { 85 struct sys_timeo *next; 86 u32_t time; 87 sys_timeout_handler h; 88 void *arg; 89 }; 90 91 struct sys_timeouts { 92 struct sys_timeo *next; 93 }; 94 95 /* sys_init() must be called before anthing else. */ 96 void sys_init(void); 97 98 /* 99 * sys_timeout(): 100 * 101 * Schedule a timeout a specified amount of milliseconds in the 102 * future. When the timeout occurs, the specified timeout handler will 103 * be called. The handler will be passed the "arg" argument when 104 * called. 105 * 106 */ 107 void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg); 108 void sys_untimeout(sys_timeout_handler h, void *arg); 109 struct sys_timeouts *sys_arch_timeouts(void); 110 111 /* Semaphore functions. */ 112 sys_sem_t sys_sem_new(u8_t count); 113 void sys_sem_signal(sys_sem_t sem); 114 u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout); 115 void sys_sem_free(sys_sem_t sem); 116 void sys_sem_wait(sys_sem_t sem); 117 int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout); 118 119 /* Time functions. */ 120 #ifndef sys_msleep 121 void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ 122 #endif 123 #ifndef sys_jiffies 124 u32_t sys_jiffies(void); /* since power up. */ 125 #endif 126 127 /* Mailbox functions. */ 128 sys_mbox_t sys_mbox_new(int size); 129 void sys_mbox_post(sys_mbox_t mbox, void *msg); 130 err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg); 131 u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout); 132 #ifndef sys_arch_mbox_tryfetch /* Allow port to override with a macro */ 133 u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg); 134 #endif 135 /* For now, we map straight to sys_arch implementation. */ 136 #define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) 137 void sys_mbox_free(sys_mbox_t mbox); 138 void sys_mbox_fetch(sys_mbox_t mbox, void **msg); 139 140 /* Thread functions. */ 141 sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio); 142 143 #endif /* NO_SYS */ 144 145 /** Returns the current time in milliseconds. */ 146 u32_t sys_now(void); 147 148 /* Critical Region Protection */ 149 /* These functions must be implemented in the sys_arch.c file. 150 In some implementations they can provide a more light-weight protection 151 mechanism than using semaphores. Otherwise semaphores can be used for 152 implementation */ 153 #ifndef SYS_ARCH_PROTECT 154 /** SYS_LIGHTWEIGHT_PROT 155 * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection 156 * for certain critical regions during buffer allocation, deallocation and memory 157 * allocation and deallocation. 158 */ 159 #if SYS_LIGHTWEIGHT_PROT 160 161 /** SYS_ARCH_DECL_PROTECT 162 * declare a protection variable. This macro will default to defining a variable of 163 * type sys_prot_t. If a particular port needs a different implementation, then 164 * this macro may be defined in sys_arch.h. 165 */ 166 #define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev 167 /** SYS_ARCH_PROTECT 168 * Perform a "fast" protect. This could be implemented by 169 * disabling interrupts for an embedded system or by using a semaphore or 170 * mutex. The implementation should allow calling SYS_ARCH_PROTECT when 171 * already protected. The old protection level is returned in the variable 172 * "lev". This macro will default to calling the sys_arch_protect() function 173 * which should be implemented in sys_arch.c. If a particular port needs a 174 * different implementation, then this macro may be defined in sys_arch.h 175 */ 176 #define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() 177 /** SYS_ARCH_UNPROTECT 178 * Perform a "fast" set of the protection level to "lev". This could be 179 * implemented by setting the interrupt level to "lev" within the MACRO or by 180 * using a semaphore or mutex. This macro will default to calling the 181 * sys_arch_unprotect() function which should be implemented in 182 * sys_arch.c. If a particular port needs a different implementation, then 183 * this macro may be defined in sys_arch.h 184 */ 185 #define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) 186 sys_prot_t sys_arch_protect(void); 187 void sys_arch_unprotect(sys_prot_t pval); 188 189 #else 190 191 #define SYS_ARCH_DECL_PROTECT(lev) 192 #define SYS_ARCH_PROTECT(lev) 193 #define SYS_ARCH_UNPROTECT(lev) 194 195 #endif /* SYS_LIGHTWEIGHT_PROT */ 196 197 #endif /* SYS_ARCH_PROTECT */ 198 199 /* 200 * Macros to set/get and increase/decrease variables in a thread-safe way. 201 * Use these for accessing variable that are used from more than one thread. 202 */ 203 204 #ifndef SYS_ARCH_INC 205 #define SYS_ARCH_INC(var, val) do { \ 206 SYS_ARCH_DECL_PROTECT(old_level); \ 207 SYS_ARCH_PROTECT(old_level); \ 208 var += val; \ 209 SYS_ARCH_UNPROTECT(old_level); \ 210 } while(0) 211 #endif /* SYS_ARCH_INC */ 212 213 #ifndef SYS_ARCH_DEC 214 #define SYS_ARCH_DEC(var, val) do { \ 215 SYS_ARCH_DECL_PROTECT(old_level); \ 216 SYS_ARCH_PROTECT(old_level); \ 217 var -= val; \ 218 SYS_ARCH_UNPROTECT(old_level); \ 219 } while(0) 220 #endif /* SYS_ARCH_DEC */ 221 222 #ifndef SYS_ARCH_GET 223 #define SYS_ARCH_GET(var, ret) do { \ 224 SYS_ARCH_DECL_PROTECT(old_level); \ 225 SYS_ARCH_PROTECT(old_level); \ 226 ret = var; \ 227 SYS_ARCH_UNPROTECT(old_level); \ 228 } while(0) 229 #endif /* SYS_ARCH_GET */ 230 231 #ifndef SYS_ARCH_SET 232 #define SYS_ARCH_SET(var, val) do { \ 233 SYS_ARCH_DECL_PROTECT(old_level); \ 234 SYS_ARCH_PROTECT(old_level); \ 235 var = val; \ 236 SYS_ARCH_UNPROTECT(old_level); \ 237 } while(0) 238 #endif /* SYS_ARCH_SET */ 239 240 241 #ifdef __cplusplus 242 } 243 #endif 244 245 #endif /* __LWIP_SYS_H__ */ 246