nkjnm

Dependencies:   MAX44000 nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns_types.h Source File

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 #if defined __GNUC__ && defined __arm__
00061 /* arm-none-eabi-gcc 4.8-2014q3 has a problem in its <inttypes.h>:
00062  * int_fast32_t is defined as int, but PRI<x>FAST32 are defined as "l<x>".
00063  * Try to detect this situation and override it.
00064  * Very hard to detect types in the preprocessor - this is best I could do.
00065  * Expansion works by:
00066  *   NS_TEST_Y(INT_FAST32_MAX) -> NS_TEST_X(2147483647) -> __NS2147483647 -> 1
00067  * Nested macros are needed so we don't get __NSINT_FAST32_MAX.
00068  */
00069 #define __NS2147483647  1
00070 #define __NS2147483647L 2
00071 #define NS_TEST_X(x) __NS##x
00072 #define NS_TEST_Y(x) NS_TEST_X(x)
00073 
00074 #if NS_TEST_Y(INT_FAST32_MAX) == __NS2147483647 && \
00075     NS_TEST_Y(INT_LEAST32_MAX) == __NS2147483647L && \
00076     NS_TEST_Y(INT32_MAX) == __NS2147483647L
00077 
00078 // Fast 32-bit types are int, others are long - this is the problem case in
00079 // arm-none-eabi-gcc.
00080 #undef PRIoFAST32
00081 #undef PRIuFAST32
00082 #undef PRIxFAST32
00083 #undef PRIXFAST32
00084 #undef PRIdFAST32
00085 #undef PRIiFAST32
00086 #define PRIoFAST32 "o"
00087 #define PRIuFAST32 "u"
00088 #define PRIxFAST32 "x"
00089 #define PRIXFAST32 "X"
00090 #define PRIdFAST32 "d"
00091 #define PRIiFAST32 "i"
00092 #endif
00093 #undef NS_TEST_X
00094 #undef NS_TEST_Y
00095 #undef __NS2147483647
00096 #undef __NS2147483647L
00097 #endif
00098 
00099 /*
00100  * Create the optional <stdint.h> 24-bit types if they don't exist (worth trying
00101  * to use them, as they could exist and be more efficient than 32-bit on 8-bit
00102  * systems...)
00103  */
00104 #ifndef UINT24_LEAST_MAX
00105 typedef uint_least32_t uint_least24_t;
00106 #define UINT_LEAST24_MAX UINT_LEAST32_MAX
00107 #define UINT24_C(x) UINT32_C(x)
00108 #define PRIoLEAST24 PRIoLEAST32
00109 #define PRIuLEAST24 PRIuLEAST32
00110 #define PRIxLEAST24 PRIxLEAST32
00111 #define PRIXLEAST24 PRIXLEAST32
00112 #endif
00113 
00114 #ifndef INT24_LEAST_MAX
00115 typedef int_least32_t int_least24_t;
00116 #define INT24_LEAST_MIN INT_LEAST32_MIN
00117 #define INT24_LEAST_MAX INT_LEAST32_MAX
00118 #define INT24_C(x) INT32_C(x)
00119 #define PRIdLEAST24 PRIdLEAST32
00120 #define PRIiLEAST24 PRIiLEAST32
00121 #endif
00122 
00123 #ifndef UINT24_FAST_MAX
00124 typedef uint_fast32_t uint_fast24_t;
00125 #define UINT_FAST24_MAX UINT_FAST32_MAX
00126 #define PRIoFAST24 PRIoFAST32
00127 #define PRIuFAST24 PRIuFAST32
00128 #define PRIxFAST24 PRIxFAST32
00129 #define PRIXFAST24 PRIXFAST32
00130 #endif
00131 
00132 #ifndef INT24_FAST_MAX
00133 typedef int_fast32_t int_fast24_t;
00134 #define INT_FAST24_MIN INT_FAST32_MIN
00135 #define INT_FAST24_MAX INT_FAST32_MAX
00136 #define PRIdFAST24 PRIdFAST32
00137 #define PRIiFAST24 PRIiFAST32
00138 #endif
00139 
00140 /* C11's "noreturn" macro, emulated if necessary */
00141 #ifndef noreturn
00142 #if defined  __cplusplus && __cplusplus >= 201103L
00143 // noreturn is a C++11 keyword
00144 #elif __STDC_VERSION__ >= 201112L
00145 #include <stdnoreturn.h>
00146 #elif defined __GNUC__
00147 #define noreturn /*__attribute__((__noreturn__))*/
00148 #elif defined __CC_ARM
00149 #define noreturn __declspec(noreturn)
00150 #elif defined __IAR_SYSTEMS_ICC__
00151 #define noreturn __noreturn
00152 #else
00153 #define noreturn
00154 #endif
00155 #endif
00156 
00157 /* C11's "alignas" macro, emulated for integer expressions if necessary */
00158 #ifndef __alignas_is_defined
00159 #if __STDC_VERSION__ >= 201112L || (defined __cplusplus && __cplusplus >= 201103L)
00160 #include <stdalign.h>
00161 #elif defined __GNUC__
00162 #define alignas(n) __attribute__((__aligned__(n)))
00163 #define __alignas_is_defined 1
00164 #elif defined __CC_ARM || defined __TASKING__
00165 #define alignas(n) __align(n)
00166 #define __alignas_is_defined 1
00167 #elif defined __IAR_SYSTEMS_ICC__
00168 /* Does this really just apply to the next variable? */
00169 #define alignas(n) __Alignas(data_alignment=n)
00170 #define __Alignas(x) _Pragma(#x)
00171 #define __alignas_is_defined 1
00172 #endif
00173 #endif
00174 
00175 /**
00176  * Marker for functions or objects that may be unused, suppressing warnings.
00177  * Place after the identifier:
00178  * ~~~
00179  *    static int X MAYBE_UNUSED = 3;
00180  *    static int foo(void) MAYBE_UNUSED;
00181  * ~~~
00182  */
00183 #if defined __CC_ARM || defined __GNUC__
00184 #define MAYBE_UNUSED __attribute__((unused))
00185 #else
00186 #define MAYBE_UNUSED
00187 #endif
00188 
00189 /*
00190  * C++ (even C++11) doesn't provide restrict: define away or provide
00191  * alternative.
00192  */
00193 #ifdef __cplusplus
00194 #ifdef __GNUC__
00195 #define restrict __restrict
00196 #else
00197 #define restrict
00198 #endif
00199 #endif /* __cplusplus */
00200 
00201 
00202 /**
00203  * C++ doesn't allow "static" in function parameter types: ie
00204  * ~~~
00205  *    entry_t *find_entry(const uint8_t address[static 16])
00206  * ~~~
00207  * If a header file may be included from C++, use this __static define instead.
00208  *
00209  * (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always
00210  * equivalent to `uint8_t *address`, but the C99 addition of static tells the
00211  * compiler that address is never NULL, and always points to at least 16
00212  * elements. This adds no new type-checking, but the information could aid
00213  * compiler optimisation, and it can serve as documentation).
00214  */
00215 #ifdef __cplusplus
00216 #define __static
00217 #else
00218 #define __static static
00219 #endif
00220 
00221 #ifdef __GNUC__
00222 #define NS_GCC_VERSION (__GNUC__ * 10000 \
00223                    + __GNUC_MINOR__ * 100 \
00224                    + __GNUC_PATCHLEVEL__)
00225 #endif
00226 
00227 /** \brief Compile-time assertion
00228  *
00229  * C11 provides _Static_assert, as does GCC even in C99 or C++ mode (and
00230  * as a freestanding implementation, we can't rely on <assert.h> to get
00231  * the static_assert macro).
00232  * C++11 provides static_assert as a keyword.
00233  *
00234  * The assertion acts as a declaration that can be placed at file scope, in a
00235  * code block (except after a label), or as a member of a struct/union. It
00236  * produces a compiler error if "test" evaluates to 0.
00237  *
00238  * Note that this *includes* the required semicolon when defined, else it
00239  * is totally empty, permitting use in structs. (If the user provided the `;`,
00240  * it would leave an illegal stray `;` if unavailable).
00241  */
00242 #if __STDC_VERSION__ >= 201112L
00243 #define NS_STATIC_ASSERT(test, str) _Static_assert(test, str);
00244 #elif defined  __cplusplus && __cplusplus >= 201103L
00245 #define NS_STATIC_ASSERT(test, str) static_assert(test, str);
00246 #elif defined __GNUC__ && NS_GCC_VERSION >= 40600
00247 //#define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str);
00248 #define NS_STATIC_ASSERT(test, str)
00249 #else
00250 #define NS_STATIC_ASSERT(test, str)
00251 #endif
00252 
00253 #define static_assert _Static_assert
00254 
00255 /** \brief Pragma to suppress warnings about unusual pointer values.
00256  *
00257  * Useful if using "poison" values.
00258  */
00259 #ifdef __IAR_SYSTEMS_ICC__
00260 #define NS_FUNNY_INTPTR_OK      _Pragma("diag_suppress=Pe1053")
00261 #define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053")
00262 #else
00263 #define NS_FUNNY_INTPTR_OK
00264 #define NS_FUNNY_INTPTR_RESTORE
00265 #endif
00266 
00267 /** \brief Convert pointer to member to pointer to containing structure */
00268 #define NS_CONTAINER_OF(ptr, type, member) \
00269     ((type *) ((char *) (ptr) - offsetof(type, member)))
00270 
00271 /*
00272  * Inlining could cause problems when mixing with C++; provide a mechanism to
00273  * disable it. This could also be turned off for other reasons (although
00274  * this can usually be done through a compiler flag, eg -O0 on gcc).
00275  */
00276 #ifndef __cplusplus
00277 #define NS_ALLOW_INLINING
00278 #endif
00279 
00280 /* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */
00281 #if defined __GNUC__ && NS_GCC_VERSION < 40600
00282 #undef NS_ALLOW_INLINING
00283 #endif
00284 
00285 /** \brief Mark a potentially-inlineable function.
00286  *
00287  * We follow C99 semantics, which requires precisely one external definition.
00288  * To also allow inlining to be totally bypassed under control of
00289  * NS_ALLOW_INLINING, code can be structured as per the example of ns_list:
00290  *
00291  * foo.h
00292  * -----
00293  * ~~~
00294  *    NS_INLINE int my_func(int);
00295  *
00296  *    #if defined NS_ALLOW_INLINING || defined FOO_FN
00297  *    #ifndef FOO_FN
00298  *    #define FOO_FN NS_INLINE
00299  *    #endif
00300  *    FOO_FN int my_func(int a)
00301  *    {
00302  *        definition;
00303  *    }
00304  *    #endif
00305  * ~~~
00306  * foo.c
00307  * -----
00308  * ~~~
00309  *    #define FOO_FN extern
00310  *    #include "foo.h"
00311  * ~~~
00312  * Which generates:
00313  * ~~~
00314  *                 NS_ALLOW_INLINING set          NS_ALLOW_INLINING unset
00315  *                 =====================          =======================
00316  *                 Include foo.h                  Include foo.h
00317  *                 -------------                  -------------
00318  *                 inline int my_func(int);       int my_func(int);
00319  *
00320  *                 // inline definition
00321  *                 inline int my_func(int a)
00322  *                 {
00323  *                     definition;
00324  *                 }
00325  *
00326  *                 Compile foo.c                  Compile foo.c
00327  *                 -------------                  -------------
00328  *    (from .h)    inline int my_func(int);       int my_func(int);
00329  *
00330  *                 // external definition
00331  *                 // because of no "inline"      // normal external definition
00332  *                 extern int my_func(int a)      extern int my_func(int a)
00333  *                 {                              {
00334  *                     definition;                    definition;
00335  *                 }                              }
00336  * ~~~
00337  *
00338  * Note that even with inline keywords, whether the compiler inlines or not is
00339  * up to it. For example, gcc at "-O0" will not inline at all, and will always
00340  * call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset.
00341  * At "-O2", gcc could potentially inline everything, meaning that foo.o is not
00342  * referenced at all.
00343  *
00344  * Alternatively, you could use "static inline", which gives every caller its
00345  * own internal definition. This is compatible with C++ inlining (which expects
00346  * the linker to eliminate duplicates), but in C it's less efficient if the code
00347  * ends up non-inlined, and it's harder to breakpoint. I don't recommend it
00348  * except for the most trivial functions (which could then probably be macros).
00349  */
00350 #ifdef NS_ALLOW_INLINING
00351 #define NS_INLINE inline
00352 #else
00353 #define NS_INLINE
00354 #endif
00355 
00356 #if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__
00357 
00358 /* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */
00359 
00360 #define NS_LARGE            __xdata
00361 #define NS_LARGE_PTR        __xdata
00362 #ifdef __ICC8051__
00363 #define NS_REENTRANT
00364 #define NS_REENTRANT_PREFIX __idata_reentrant
00365 #else
00366 #define NS_REENTRANT        __reentrant
00367 #define NS_REENTRANT_PREFIX
00368 #endif
00369 #define NS_NEAR_FUNC        __near_func
00370 
00371 #else
00372 
00373 /* "Normal" systems. Define it all away. */
00374 #define NS_LARGE
00375 #define NS_LARGE_PTR
00376 #define NS_REENTRANT
00377 #define NS_REENTRANT_PREFIX
00378 #define NS_NEAR_FUNC
00379 
00380 #endif
00381 
00382 /** \brief Scatter-gather descriptor
00383  *
00384  * Slightly optimised for small platforms - we assume we won't need any
00385  * element bigger than 64K.
00386  */
00387 typedef struct ns_iovec
00388 {
00389     void *iov_base;
00390     uint_fast16_t iov_len;
00391 } ns_iovec_t;
00392 #endif /* NS_TYPES_H */