Mbed library for ENC28J60 Ethernet modules. Full support for TCP/IP and UDP Server, Client and HTTP server (webserver). DHCP and DNS is included.
Dependents: mBuino_ENC28_MQTT Nucleo_Web_ENC28J60 Nucleo_Web_ENC28J60_ADC Serial_over_Ethernet ... more
ns_types.h
00001 /* 00002 * Copyright (c) 2014-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 /* 00017 * ns_types.h - Basic compiler and type setup for Nanostack libraries. 00018 */ 00019 #ifndef NS_TYPES_H_ 00020 #define NS_TYPES_H_ 00021 00022 /** \file 00023 * \brief Basic compiler and type setup 00024 * 00025 * We currently assume C99 or later. 00026 * 00027 * C99 features being relied on: 00028 * 00029 * - <inttypes.h> and <stdbool.h> 00030 * - inline (with C99 semantics, not C++ as per default GCC); 00031 * - designated initialisers; 00032 * - compound literals; 00033 * - restrict; 00034 * - [static N] in array parameters; 00035 * - declarations in for statements; 00036 * - mixing declarations and statements 00037 * 00038 * Compilers should be set to C99 or later mode when building Nanomesh source. 00039 * For GCC this means "-std=gnu99" (C99 with usual GNU extensions). 00040 * 00041 * Also, a little extra care is required for public header files that could be 00042 * included from C++, especially as C++ lacks some C99 features. 00043 * 00044 * (TODO: as this is exposed to API users, do we need a predefine to distinguish 00045 * internal and external use, for finer control? Not yet, but maybe...) 00046 */ 00047 00048 /* Make sure <stdint.h> defines its macros if C++ */ 00049 #ifndef __STDC_LIMIT_MACROS 00050 #define __STDC_LIMIT_MACROS 00051 #endif 00052 #ifndef __STDC_CONSTANT_MACROS 00053 #define __STDC_CONSTANT_MACROS 00054 #endif 00055 00056 #include <stddef.h> 00057 #include <inttypes.h> // includes <stdint.h>; debugf() users need PRIu32 etc 00058 #include <stdbool.h> 00059 00060 /* 00061 * Create the optional <stdint.h> 24-bit types if they don't exist (worth trying 00062 * to use them, as they could exist and be more efficient than 32-bit on 8-bit 00063 * systems...) 00064 */ 00065 #ifndef UINT_LEAST24_MAX 00066 typedef uint_least32_t uint_least24_t; 00067 #define UINT_LEAST24_MAX UINT_LEAST32_MAX 00068 #define UINT24_C(x) UINT32_C(x) 00069 #define PRIoLEAST24 PRIoLEAST32 00070 #define PRIuLEAST24 PRIuLEAST32 00071 #define PRIxLEAST24 PRIxLEAST32 00072 #define PRIXLEAST24 PRIXLEAST32 00073 #endif 00074 00075 #ifndef INT_LEAST24_MAX 00076 typedef int_least32_t int_least24_t; 00077 #define INT_LEAST24_MIN INT_LEAST32_MIN 00078 #define INT_LEAST24_MAX INT_LEAST32_MAX 00079 #define INT24_C(x) INT32_C(x) 00080 #define PRIdLEAST24 PRIdLEAST32 00081 #define PRIiLEAST24 PRIiLEAST32 00082 #endif 00083 00084 #ifndef UINT_FAST24_MAX 00085 typedef uint_fast32_t uint_fast24_t; 00086 #define UINT_FAST24_MAX UINT_FAST32_MAX 00087 #define PRIoFAST24 PRIoFAST32 00088 #define PRIuFAST24 PRIuFAST32 00089 #define PRIxFAST24 PRIxFAST32 00090 #define PRIXFAST24 PRIXFAST32 00091 #endif 00092 00093 #ifndef INT_FAST24_MAX 00094 typedef int_fast32_t int_fast24_t; 00095 #define INT_FAST24_MIN INT_FAST32_MIN 00096 #define INT_FAST24_MAX INT_FAST32_MAX 00097 #define PRIdFAST24 PRIdFAST32 00098 #define PRIiFAST24 PRIiFAST32 00099 #endif 00100 00101 /* Function attribute - C11 "noreturn" or C++11 "[[noreturn]]" */ 00102 #ifndef NS_NORETURN 00103 #if defined __cplusplus && __cplusplus >= 201103L 00104 #define NS_NORETURN [[noreturn]] 00105 #elif !defined __cplusplus && __STDC_VERSION__ >= 201112L 00106 #define NS_NORETURN _Noreturn 00107 #elif defined __GNUC__ 00108 #define NS_NORETURN __attribute__((__noreturn__)) 00109 #elif defined __CC_ARM 00110 #define NS_NORETURN __declspec(noreturn) 00111 #elif defined __IAR_SYSTEMS_ICC__ 00112 #define NS_NORETURN __noreturn 00113 #else 00114 #define NS_NORETURN 00115 #endif 00116 #endif 00117 00118 /* C11's "alignas" macro, emulated for integer expressions if necessary */ 00119 #ifndef __alignas_is_defined 00120 #if defined __CC_ARM || defined __TASKING__ 00121 #define alignas(n) __align(n) 00122 #define __alignas_is_defined 1 00123 #elif (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L) || (defined __cplusplus && __cplusplus >= 201103L) 00124 # if defined __ARMCC_VERSION && __ARMCC_VERSION < 6120000 00125 /* Workaround for Arm Compiler versions prior to 6.12 */ 00126 # if !defined __cplusplus 00127 # define alignas _Alignas 00128 # endif 00129 # define __alignas_is_defined 1 00130 # else 00131 # include <stdalign.h> 00132 # endif 00133 #elif defined __GNUC__ 00134 #define alignas(n) __attribute__((__aligned__(n))) 00135 #define __alignas_is_defined 1 00136 #elif defined __IAR_SYSTEMS_ICC__ 00137 /* Does this really just apply to the next variable? */ 00138 #define alignas(n) __Alignas(data_alignment=n) 00139 #define __Alignas(x) _Pragma(#x) 00140 #define __alignas_is_defined 1 00141 #endif 00142 #endif 00143 00144 /** 00145 * Marker for functions or objects that may be unused, suppressing warnings. 00146 * Place after the identifier: 00147 * ~~~ 00148 * static int X MAYBE_UNUSED = 3; 00149 * static int foo(void) MAYBE_UNUSED; 00150 * ~~~ 00151 */ 00152 #if defined __CC_ARM || defined __GNUC__ 00153 #define MAYBE_UNUSED __attribute__((unused)) 00154 #else 00155 #define MAYBE_UNUSED 00156 #endif 00157 00158 /* 00159 * C++ (even C++11) doesn't provide restrict: define away or provide 00160 * alternative. 00161 */ 00162 #ifdef __cplusplus 00163 #ifdef __GNUC__ 00164 #define restrict __restrict 00165 #else 00166 #define restrict 00167 #endif 00168 #endif /* __cplusplus */ 00169 00170 00171 /** 00172 * C++ doesn't allow "static" in function parameter types: ie 00173 * ~~~ 00174 * entry_t *find_entry(const uint8_t address[static 16]) 00175 * ~~~ 00176 * If a header file may be included from C++, use this __static define instead. 00177 * 00178 * (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always 00179 * equivalent to `uint8_t *address`, but the C99 addition of static tells the 00180 * compiler that address is never NULL, and always points to at least 16 00181 * elements. This adds no new type-checking, but the information could aid 00182 * compiler optimisation, and it can serve as documentation). 00183 */ 00184 #ifdef __cplusplus 00185 #define __static 00186 #else 00187 #define __static static 00188 #endif 00189 00190 #ifdef __GNUC__ 00191 #define NS_GCC_VERSION (__GNUC__ * 10000 \ 00192 + __GNUC_MINOR__ * 100 \ 00193 + __GNUC_PATCHLEVEL__) 00194 #endif 00195 00196 /** \brief Compile-time assertion 00197 * 00198 * C11 provides _Static_assert, as does GCC even in C99 mode (and 00199 * as a freestanding implementation, we can't rely on <assert.h> to get 00200 * the static_assert macro). 00201 * C++11 provides static_assert as a keyword, as does G++ in C++0x mode. 00202 * 00203 * The assertion acts as a declaration that can be placed at file scope, in a 00204 * code block (except after a label), or as a member of a struct/union. It 00205 * produces a compiler error if "test" evaluates to 0. 00206 * 00207 * Note that this *includes* the required semicolon when defined, else it 00208 * is totally empty, permitting use in structs. (If the user provided the `;`, 00209 * it would leave an illegal stray `;` if unavailable). 00210 */ 00211 #ifdef __cplusplus 00212 # if __cplusplus >= 201103L || __cpp_static_assert >= 200410 00213 # define NS_STATIC_ASSERT(test, str) static_assert(test, str); 00214 # elif defined __GXX_EXPERIMENTAL_CXX0X__ && NS_GCC_VERSION >= 40300 00215 # define NS_STATIC_ASSERT(test, str) __extension__ static_assert(test, str); 00216 # else 00217 # define NS_STATIC_ASSERT(test, str) 00218 # endif 00219 #else /* C */ 00220 # if __STDC_VERSION__ >= 201112L 00221 # define NS_STATIC_ASSERT(test, str) _Static_assert(test, str); 00222 # elif defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM 00223 # ifdef _Static_assert 00224 /* 00225 * Some versions of glibc cdefs.h (which comes in via <stdint.h> above) 00226 * attempt to define their own _Static_assert (if GCC < 4.6 or 00227 * __STRICT_ANSI__) using an extern declaration, which doesn't work in a 00228 * struct/union. 00229 * 00230 * For GCC >= 4.6 and __STRICT_ANSI__, we can do better - just use 00231 * the built-in _Static_assert with __extension__. We have to do this, as 00232 * ns_list.h needs to use it in a union. No way to get at it though, without 00233 * overriding their define. 00234 */ 00235 # undef _Static_assert 00236 # define _Static_assert(x, y) __extension__ _Static_assert(x, y) 00237 # endif 00238 # define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str); 00239 # else 00240 # define NS_STATIC_ASSERT(test, str) 00241 #endif 00242 #endif 00243 00244 /** \brief Pragma to suppress warnings about unusual pointer values. 00245 * 00246 * Useful if using "poison" values. 00247 */ 00248 #ifdef __IAR_SYSTEMS_ICC__ 00249 #define NS_FUNNY_INTPTR_OK _Pragma("diag_suppress=Pe1053") 00250 #define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053") 00251 #else 00252 #define NS_FUNNY_INTPTR_OK 00253 #define NS_FUNNY_INTPTR_RESTORE 00254 #endif 00255 00256 /** \brief Pragma to suppress warnings about always true/false comparisons 00257 */ 00258 #if defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM 00259 #define NS_FUNNY_COMPARE_OK _Pragma("GCC diagnostic push") \ 00260 _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") 00261 #define NS_FUNNY_COMPARE_RESTORE _Pragma("GCC diagnostic pop") 00262 #else 00263 #define NS_FUNNY_COMPARE_OK 00264 #define NS_FUNNY_COMPARE_RESTORE 00265 #endif 00266 00267 /** \brief Pragma to suppress warnings arising from dummy definitions. 00268 * 00269 * Useful when you have function-like macros that returning constants 00270 * in cut-down builds. Can be fairly cavalier about disabling as we 00271 * do not expect every build to use this macro. Generic builds of 00272 * components should ensure this is not included by only using it in 00273 * a ifdef blocks providing dummy definitions. 00274 */ 00275 #ifdef __CC_ARM 00276 // statement is unreachable(111), controlling expression is constant(236), expression has no effect(174), 00277 // function was declared but never referenced(177), variable was set but never used(550) 00278 #define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=111,236,174,177,550") 00279 #elif defined __IAR_SYSTEMS_ICC__ 00280 // controlling expression is constant 00281 #define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=Pe236") 00282 #else 00283 #define NS_DUMMY_DEFINITIONS_OK 00284 #endif 00285 00286 /** \brief Convert pointer to member to pointer to containing structure */ 00287 #define NS_CONTAINER_OF(ptr, type, member) \ 00288 ((type *) ((char *) (ptr) - offsetof(type, member))) 00289 00290 /* 00291 * Inlining could cause problems when mixing with C++; provide a mechanism to 00292 * disable it. This could also be turned off for other reasons (although 00293 * this can usually be done through a compiler flag, eg -O0 on gcc). 00294 */ 00295 #ifndef __cplusplus 00296 #define NS_ALLOW_INLINING 00297 #endif 00298 00299 /* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */ 00300 #if defined __GNUC__ && NS_GCC_VERSION < 40600 00301 #undef NS_ALLOW_INLINING 00302 #endif 00303 00304 /** \brief Mark a potentially-inlineable function. 00305 * 00306 * We follow C99 semantics, which requires precisely one external definition. 00307 * To also allow inlining to be totally bypassed under control of 00308 * NS_ALLOW_INLINING, code can be structured as per the example of ns_list: 00309 * 00310 * foo.h 00311 * ----- 00312 * ~~~ 00313 * NS_INLINE int my_func(int); 00314 * 00315 * #if defined NS_ALLOW_INLINING || defined FOO_FN 00316 * #ifndef FOO_FN 00317 * #define FOO_FN NS_INLINE 00318 * #endif 00319 * FOO_FN int my_func(int a) 00320 * { 00321 * definition; 00322 * } 00323 * #endif 00324 * ~~~ 00325 * foo.c 00326 * ----- 00327 * ~~~ 00328 * #define FOO_FN extern 00329 * #include "foo.h" 00330 * ~~~ 00331 * Which generates: 00332 * ~~~ 00333 * NS_ALLOW_INLINING set NS_ALLOW_INLINING unset 00334 * ===================== ======================= 00335 * Include foo.h Include foo.h 00336 * ------------- ------------- 00337 * inline int my_func(int); int my_func(int); 00338 * 00339 * // inline definition 00340 * inline int my_func(int a) 00341 * { 00342 * definition; 00343 * } 00344 * 00345 * Compile foo.c Compile foo.c 00346 * ------------- ------------- 00347 * (from .h) inline int my_func(int); int my_func(int); 00348 * 00349 * // external definition 00350 * // because of no "inline" // normal external definition 00351 * extern int my_func(int a) extern int my_func(int a) 00352 * { { 00353 * definition; definition; 00354 * } } 00355 * ~~~ 00356 * 00357 * Note that even with inline keywords, whether the compiler inlines or not is 00358 * up to it. For example, gcc at "-O0" will not inline at all, and will always 00359 * call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset. 00360 * At "-O2", gcc could potentially inline everything, meaning that foo.o is not 00361 * referenced at all. 00362 * 00363 * Alternatively, you could use "static inline", which gives every caller its 00364 * own internal definition. This is compatible with C++ inlining (which expects 00365 * the linker to eliminate duplicates), but in C it's less efficient if the code 00366 * ends up non-inlined, and it's harder to breakpoint. I don't recommend it 00367 * except for the most trivial functions (which could then probably be macros). 00368 */ 00369 #ifdef NS_ALLOW_INLINING 00370 #define NS_INLINE inline 00371 #else 00372 #define NS_INLINE 00373 #endif 00374 00375 #if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__ 00376 00377 /* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */ 00378 00379 #define NS_LARGE __xdata 00380 #define NS_LARGE_PTR __xdata 00381 #ifdef __ICC8051__ 00382 #define NS_REENTRANT 00383 #define NS_REENTRANT_PREFIX __idata_reentrant 00384 #else 00385 #define NS_REENTRANT __reentrant 00386 #define NS_REENTRANT_PREFIX 00387 #endif 00388 #define NS_NEAR_FUNC __near_func 00389 00390 #else 00391 00392 /* "Normal" systems. Define it all away. */ 00393 #define NS_LARGE 00394 #define NS_LARGE_PTR 00395 #define NS_REENTRANT 00396 #define NS_REENTRANT_PREFIX 00397 #define NS_NEAR_FUNC 00398 00399 #endif 00400 00401 /** \brief Scatter-gather descriptor 00402 * 00403 * Slightly optimised for small platforms - we assume we won't need any 00404 * element bigger than 64K. 00405 */ 00406 typedef struct ns_iovec { 00407 void *iov_base; 00408 uint_fast16_t iov_len; 00409 } ns_iovec_t; 00410 00411 #endif /* NS_TYPES_H */
Generated on Tue Jul 12 2022 18:48:00 by 1.7.2