Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
ns_types.h
Go to the documentation of this file.
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 (__STDC_VERSION__ >= 201112L) || (defined __cplusplus && __cplusplus >= 201103L) 00124 #include <stdalign.h> 00125 #elif defined __GNUC__ 00126 #define alignas(n) __attribute__((__aligned__(n))) 00127 #define __alignas_is_defined 1 00128 #elif defined __IAR_SYSTEMS_ICC__ 00129 /* Does this really just apply to the next variable? */ 00130 #define alignas(n) __Alignas(data_alignment=n) 00131 #define __Alignas(x) _Pragma(#x) 00132 #define __alignas_is_defined 1 00133 #endif 00134 #endif 00135 00136 /** 00137 * Marker for functions or objects that may be unused, suppressing warnings. 00138 * Place after the identifier: 00139 * ~~~ 00140 * static int X MAYBE_UNUSED = 3; 00141 * static int foo(void) MAYBE_UNUSED; 00142 * ~~~ 00143 */ 00144 #if defined __CC_ARM || defined __GNUC__ 00145 #define MAYBE_UNUSED __attribute__((unused)) 00146 #else 00147 #define MAYBE_UNUSED 00148 #endif 00149 00150 /* 00151 * C++ (even C++11) doesn't provide restrict: define away or provide 00152 * alternative. 00153 */ 00154 #ifdef __cplusplus 00155 #ifdef __GNUC__ 00156 #define restrict __restrict 00157 #else 00158 #define restrict 00159 #endif 00160 #endif /* __cplusplus */ 00161 00162 00163 /** 00164 * C++ doesn't allow "static" in function parameter types: ie 00165 * ~~~ 00166 * entry_t *find_entry(const uint8_t address[static 16]) 00167 * ~~~ 00168 * If a header file may be included from C++, use this __static define instead. 00169 * 00170 * (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always 00171 * equivalent to `uint8_t *address`, but the C99 addition of static tells the 00172 * compiler that address is never NULL, and always points to at least 16 00173 * elements. This adds no new type-checking, but the information could aid 00174 * compiler optimisation, and it can serve as documentation). 00175 */ 00176 #ifdef __cplusplus 00177 #define __static 00178 #else 00179 #define __static static 00180 #endif 00181 00182 #ifdef __GNUC__ 00183 #define NS_GCC_VERSION (__GNUC__ * 10000 \ 00184 + __GNUC_MINOR__ * 100 \ 00185 + __GNUC_PATCHLEVEL__) 00186 #endif 00187 00188 /** \brief Compile-time assertion 00189 * 00190 * C11 provides _Static_assert, as does GCC even in C99 mode (and 00191 * as a freestanding implementation, we can't rely on <assert.h> to get 00192 * the static_assert macro). 00193 * C++11 provides static_assert as a keyword, as does G++ in C++0x mode. 00194 * 00195 * The assertion acts as a declaration that can be placed at file scope, in a 00196 * code block (except after a label), or as a member of a struct/union. It 00197 * produces a compiler error if "test" evaluates to 0. 00198 * 00199 * Note that this *includes* the required semicolon when defined, else it 00200 * is totally empty, permitting use in structs. (If the user provided the `;`, 00201 * it would leave an illegal stray `;` if unavailable). 00202 */ 00203 #ifdef __cplusplus 00204 # if __cplusplus >= 201103L || __cpp_static_assert >= 200410 00205 # define NS_STATIC_ASSERT(test, str) static_assert(test, str); 00206 # elif defined __GXX_EXPERIMENTAL_CXX0X__ && NS_GCC_VERSION >= 40300 00207 # define NS_STATIC_ASSERT(test, str) __extension__ static_assert(test, str); 00208 # else 00209 # define NS_STATIC_ASSERT(test, str) 00210 # endif 00211 #else /* C */ 00212 # if __STDC_VERSION__ >= 201112L 00213 # define NS_STATIC_ASSERT(test, str) _Static_assert(test, str); 00214 # elif defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM 00215 # ifdef _Static_assert 00216 /* 00217 * Some versions of glibc cdefs.h (which comes in via <stdint.h> above) 00218 * attempt to define their own _Static_assert (if GCC < 4.6 or 00219 * __STRICT_ANSI__) using an extern declaration, which doesn't work in a 00220 * struct/union. 00221 * 00222 * For GCC >= 4.6 and __STRICT_ANSI__, we can do better - just use 00223 * the built-in _Static_assert with __extension__. We have to do this, as 00224 * ns_list.h needs to use it in a union. No way to get at it though, without 00225 * overriding their define. 00226 */ 00227 # undef _Static_assert 00228 # define _Static_assert(x, y) __extension__ _Static_assert(x, y) 00229 # endif 00230 # define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str); 00231 # else 00232 # define NS_STATIC_ASSERT(test, str) 00233 #endif 00234 #endif 00235 00236 /** \brief Pragma to suppress warnings about unusual pointer values. 00237 * 00238 * Useful if using "poison" values. 00239 */ 00240 #ifdef __IAR_SYSTEMS_ICC__ 00241 #define NS_FUNNY_INTPTR_OK _Pragma("diag_suppress=Pe1053") 00242 #define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053") 00243 #else 00244 #define NS_FUNNY_INTPTR_OK 00245 #define NS_FUNNY_INTPTR_RESTORE 00246 #endif 00247 00248 /** \brief Pragma to suppress warnings about always true/false comparisons 00249 */ 00250 #if defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM 00251 #define NS_FUNNY_COMPARE_OK _Pragma("GCC diagnostic push") \ 00252 _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") 00253 #define NS_FUNNY_COMPARE_RESTORE _Pragma("GCC diagnostic pop") 00254 #else 00255 #define NS_FUNNY_COMPARE_OK 00256 #define NS_FUNNY_COMPARE_RESTORE 00257 #endif 00258 00259 /** \brief Pragma to suppress warnings arising from dummy definitions. 00260 * 00261 * Useful when you have function-like macros that returning constants 00262 * in cut-down builds. Can be fairly cavalier about disabling as we 00263 * do not expect every build to use this macro. Generic builds of 00264 * components should ensure this is not included by only using it in 00265 * a ifdef blocks providing dummy definitions. 00266 */ 00267 #ifdef __CC_ARM 00268 // statement is unreachable(111), controlling expression is constant(236), expression has no effect(174), 00269 // function was declared but never referenced(177), variable was set but never used(550) 00270 #define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=111,236,174,177,550") 00271 #elif defined __IAR_SYSTEMS_ICC__ 00272 // controlling expression is constant 00273 #define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=Pe236") 00274 #else 00275 #define NS_DUMMY_DEFINITIONS_OK 00276 #endif 00277 00278 /** \brief Convert pointer to member to pointer to containing structure */ 00279 #define NS_CONTAINER_OF(ptr, type, member) \ 00280 ((type *) ((char *) (ptr) - offsetof(type, member))) 00281 00282 /* 00283 * Inlining could cause problems when mixing with C++; provide a mechanism to 00284 * disable it. This could also be turned off for other reasons (although 00285 * this can usually be done through a compiler flag, eg -O0 on gcc). 00286 */ 00287 #ifndef __cplusplus 00288 #define NS_ALLOW_INLINING 00289 #endif 00290 00291 /* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */ 00292 #if defined __GNUC__ && NS_GCC_VERSION < 40600 00293 #undef NS_ALLOW_INLINING 00294 #endif 00295 00296 /** \brief Mark a potentially-inlineable function. 00297 * 00298 * We follow C99 semantics, which requires precisely one external definition. 00299 * To also allow inlining to be totally bypassed under control of 00300 * NS_ALLOW_INLINING, code can be structured as per the example of ns_list: 00301 * 00302 * foo.h 00303 * ----- 00304 * ~~~ 00305 * NS_INLINE int my_func(int); 00306 * 00307 * #if defined NS_ALLOW_INLINING || defined FOO_FN 00308 * #ifndef FOO_FN 00309 * #define FOO_FN NS_INLINE 00310 * #endif 00311 * FOO_FN int my_func(int a) 00312 * { 00313 * definition; 00314 * } 00315 * #endif 00316 * ~~~ 00317 * foo.c 00318 * ----- 00319 * ~~~ 00320 * #define FOO_FN extern 00321 * #include "foo.h" 00322 * ~~~ 00323 * Which generates: 00324 * ~~~ 00325 * NS_ALLOW_INLINING set NS_ALLOW_INLINING unset 00326 * ===================== ======================= 00327 * Include foo.h Include foo.h 00328 * ------------- ------------- 00329 * inline int my_func(int); int my_func(int); 00330 * 00331 * // inline definition 00332 * inline int my_func(int a) 00333 * { 00334 * definition; 00335 * } 00336 * 00337 * Compile foo.c Compile foo.c 00338 * ------------- ------------- 00339 * (from .h) inline int my_func(int); int my_func(int); 00340 * 00341 * // external definition 00342 * // because of no "inline" // normal external definition 00343 * extern int my_func(int a) extern int my_func(int a) 00344 * { { 00345 * definition; definition; 00346 * } } 00347 * ~~~ 00348 * 00349 * Note that even with inline keywords, whether the compiler inlines or not is 00350 * up to it. For example, gcc at "-O0" will not inline at all, and will always 00351 * call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset. 00352 * At "-O2", gcc could potentially inline everything, meaning that foo.o is not 00353 * referenced at all. 00354 * 00355 * Alternatively, you could use "static inline", which gives every caller its 00356 * own internal definition. This is compatible with C++ inlining (which expects 00357 * the linker to eliminate duplicates), but in C it's less efficient if the code 00358 * ends up non-inlined, and it's harder to breakpoint. I don't recommend it 00359 * except for the most trivial functions (which could then probably be macros). 00360 */ 00361 #ifdef NS_ALLOW_INLINING 00362 #define NS_INLINE inline 00363 #else 00364 #define NS_INLINE 00365 #endif 00366 00367 #if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__ 00368 00369 /* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */ 00370 00371 #define NS_LARGE __xdata 00372 #define NS_LARGE_PTR __xdata 00373 #ifdef __ICC8051__ 00374 #define NS_REENTRANT 00375 #define NS_REENTRANT_PREFIX __idata_reentrant 00376 #else 00377 #define NS_REENTRANT __reentrant 00378 #define NS_REENTRANT_PREFIX 00379 #endif 00380 #define NS_NEAR_FUNC __near_func 00381 00382 #else 00383 00384 /* "Normal" systems. Define it all away. */ 00385 #define NS_LARGE 00386 #define NS_LARGE_PTR 00387 #define NS_REENTRANT 00388 #define NS_REENTRANT_PREFIX 00389 #define NS_NEAR_FUNC 00390 00391 #endif 00392 00393 /** \brief Scatter-gather descriptor 00394 * 00395 * Slightly optimised for small platforms - we assume we won't need any 00396 * element bigger than 64K. 00397 */ 00398 typedef struct ns_iovec { 00399 void *iov_base; 00400 uint_fast16_t iov_len; 00401 } ns_iovec_t; 00402 00403 #endif /* NS_TYPES_H */
Generated on Sun Jul 17 2022 08:25:28 by 1.7.2