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

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 /*
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 */