ex
Fork of mbed-os-example-mbed5-blinky by
DuerOS-Light-SDK-v1.1.0/duer-os-light/src/iot-baidu-ca/source/ns_types.h@47:9e361da97763, 2017-07-18 (annotated)
- Committer:
- TMBOY
- Date:
- Tue Jul 18 16:54:45 2017 +0800
- Revision:
- 47:9e361da97763
?
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| TMBOY | 47:9e361da97763 | 1 | /* |
| TMBOY | 47:9e361da97763 | 2 | * Copyright (c) 2014-2015 ARM Limited. All rights reserved. |
| TMBOY | 47:9e361da97763 | 3 | * SPDX-License-Identifier: Apache-2.0 |
| TMBOY | 47:9e361da97763 | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
| TMBOY | 47:9e361da97763 | 5 | * not use this file except in compliance with the License. |
| TMBOY | 47:9e361da97763 | 6 | * You may obtain a copy of the License at |
| TMBOY | 47:9e361da97763 | 7 | * |
| TMBOY | 47:9e361da97763 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| TMBOY | 47:9e361da97763 | 9 | * |
| TMBOY | 47:9e361da97763 | 10 | * Unless required by applicable law or agreed to in writing, software |
| TMBOY | 47:9e361da97763 | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
| TMBOY | 47:9e361da97763 | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| TMBOY | 47:9e361da97763 | 13 | * See the License for the specific language governing permissions and |
| TMBOY | 47:9e361da97763 | 14 | * limitations under the License. |
| TMBOY | 47:9e361da97763 | 15 | */ |
| TMBOY | 47:9e361da97763 | 16 | /* |
| TMBOY | 47:9e361da97763 | 17 | * ns_types.h - Basic compiler and type setup for Nanostack libraries. |
| TMBOY | 47:9e361da97763 | 18 | */ |
| TMBOY | 47:9e361da97763 | 19 | #ifndef NS_TYPES_H_ |
| TMBOY | 47:9e361da97763 | 20 | #define NS_TYPES_H_ |
| TMBOY | 47:9e361da97763 | 21 | |
| TMBOY | 47:9e361da97763 | 22 | /** \file |
| TMBOY | 47:9e361da97763 | 23 | * \brief Basic compiler and type setup |
| TMBOY | 47:9e361da97763 | 24 | * |
| TMBOY | 47:9e361da97763 | 25 | * We currently assume C99 or later. |
| TMBOY | 47:9e361da97763 | 26 | * |
| TMBOY | 47:9e361da97763 | 27 | * C99 features being relied on: |
| TMBOY | 47:9e361da97763 | 28 | * |
| TMBOY | 47:9e361da97763 | 29 | * - <inttypes.h> and <stdbool.h> |
| TMBOY | 47:9e361da97763 | 30 | * - inline (with C99 semantics, not C++ as per default GCC); |
| TMBOY | 47:9e361da97763 | 31 | * - designated initialisers; |
| TMBOY | 47:9e361da97763 | 32 | * - compound literals; |
| TMBOY | 47:9e361da97763 | 33 | * - restrict; |
| TMBOY | 47:9e361da97763 | 34 | * - [static N] in array parameters; |
| TMBOY | 47:9e361da97763 | 35 | * - declarations in for statements; |
| TMBOY | 47:9e361da97763 | 36 | * - mixing declarations and statements |
| TMBOY | 47:9e361da97763 | 37 | * |
| TMBOY | 47:9e361da97763 | 38 | * Compilers should be set to C99 or later mode when building Nanomesh source. |
| TMBOY | 47:9e361da97763 | 39 | * For GCC this means "-std=gnu99" (C99 with usual GNU extensions). |
| TMBOY | 47:9e361da97763 | 40 | * |
| TMBOY | 47:9e361da97763 | 41 | * Also, a little extra care is required for public header files that could be |
| TMBOY | 47:9e361da97763 | 42 | * included from C++, especially as C++ lacks some C99 features. |
| TMBOY | 47:9e361da97763 | 43 | * |
| TMBOY | 47:9e361da97763 | 44 | * (TODO: as this is exposed to API users, do we need a predefine to distinguish |
| TMBOY | 47:9e361da97763 | 45 | * internal and external use, for finer control? Not yet, but maybe...) |
| TMBOY | 47:9e361da97763 | 46 | */ |
| TMBOY | 47:9e361da97763 | 47 | |
| TMBOY | 47:9e361da97763 | 48 | /* Make sure <stdint.h> defines its macros if C++ */ |
| TMBOY | 47:9e361da97763 | 49 | #ifndef __STDC_LIMIT_MACROS |
| TMBOY | 47:9e361da97763 | 50 | #define __STDC_LIMIT_MACROS |
| TMBOY | 47:9e361da97763 | 51 | #endif |
| TMBOY | 47:9e361da97763 | 52 | #ifndef __STDC_CONSTANT_MACROS |
| TMBOY | 47:9e361da97763 | 53 | #define __STDC_CONSTANT_MACROS |
| TMBOY | 47:9e361da97763 | 54 | #endif |
| TMBOY | 47:9e361da97763 | 55 | |
| TMBOY | 47:9e361da97763 | 56 | #include <stddef.h> |
| TMBOY | 47:9e361da97763 | 57 | #include <inttypes.h> // includes <stdint.h>; debugf() users need PRIu32 etc |
| TMBOY | 47:9e361da97763 | 58 | #include <stdbool.h> |
| TMBOY | 47:9e361da97763 | 59 | |
| TMBOY | 47:9e361da97763 | 60 | #if defined __GNUC__ && defined __arm__ |
| TMBOY | 47:9e361da97763 | 61 | /* arm-none-eabi-gcc 4.8-2014q3 has a problem in its <inttypes.h>: |
| TMBOY | 47:9e361da97763 | 62 | * int_fast32_t is defined as int, but PRI<x>FAST32 are defined as "l<x>". |
| TMBOY | 47:9e361da97763 | 63 | * Try to detect this situation and override it. |
| TMBOY | 47:9e361da97763 | 64 | * Very hard to detect types in the preprocessor - this is best I could do. |
| TMBOY | 47:9e361da97763 | 65 | * Expansion works by: |
| TMBOY | 47:9e361da97763 | 66 | * NS_TEST_Y(INT_FAST32_MAX) -> NS_TEST_X(2147483647) -> __NS2147483647 -> 1 |
| TMBOY | 47:9e361da97763 | 67 | * Nested macros are needed so we don't get __NSINT_FAST32_MAX. |
| TMBOY | 47:9e361da97763 | 68 | */ |
| TMBOY | 47:9e361da97763 | 69 | #define __NS2147483647 1 |
| TMBOY | 47:9e361da97763 | 70 | #define __NS2147483647L 2 |
| TMBOY | 47:9e361da97763 | 71 | #define NS_TEST_X(x) __NS##x |
| TMBOY | 47:9e361da97763 | 72 | #define NS_TEST_Y(x) NS_TEST_X(x) |
| TMBOY | 47:9e361da97763 | 73 | |
| TMBOY | 47:9e361da97763 | 74 | #if NS_TEST_Y(INT_FAST32_MAX) == __NS2147483647 && \ |
| TMBOY | 47:9e361da97763 | 75 | NS_TEST_Y(INT_LEAST32_MAX) == __NS2147483647L && \ |
| TMBOY | 47:9e361da97763 | 76 | NS_TEST_Y(INT32_MAX) == __NS2147483647L |
| TMBOY | 47:9e361da97763 | 77 | |
| TMBOY | 47:9e361da97763 | 78 | // Fast 32-bit types are int, others are long - this is the problem case in |
| TMBOY | 47:9e361da97763 | 79 | // arm-none-eabi-gcc. |
| TMBOY | 47:9e361da97763 | 80 | #undef PRIoFAST32 |
| TMBOY | 47:9e361da97763 | 81 | #undef PRIuFAST32 |
| TMBOY | 47:9e361da97763 | 82 | #undef PRIxFAST32 |
| TMBOY | 47:9e361da97763 | 83 | #undef PRIXFAST32 |
| TMBOY | 47:9e361da97763 | 84 | #undef PRIdFAST32 |
| TMBOY | 47:9e361da97763 | 85 | #undef PRIiFAST32 |
| TMBOY | 47:9e361da97763 | 86 | #define PRIoFAST32 "o" |
| TMBOY | 47:9e361da97763 | 87 | #define PRIuFAST32 "u" |
| TMBOY | 47:9e361da97763 | 88 | #define PRIxFAST32 "x" |
| TMBOY | 47:9e361da97763 | 89 | #define PRIXFAST32 "X" |
| TMBOY | 47:9e361da97763 | 90 | #define PRIdFAST32 "d" |
| TMBOY | 47:9e361da97763 | 91 | #define PRIiFAST32 "i" |
| TMBOY | 47:9e361da97763 | 92 | #endif |
| TMBOY | 47:9e361da97763 | 93 | #undef NS_TEST_X |
| TMBOY | 47:9e361da97763 | 94 | #undef NS_TEST_Y |
| TMBOY | 47:9e361da97763 | 95 | #undef __NS2147483647 |
| TMBOY | 47:9e361da97763 | 96 | #undef __NS2147483647L |
| TMBOY | 47:9e361da97763 | 97 | #endif |
| TMBOY | 47:9e361da97763 | 98 | |
| TMBOY | 47:9e361da97763 | 99 | /* |
| TMBOY | 47:9e361da97763 | 100 | * Create the optional <stdint.h> 24-bit types if they don't exist (worth trying |
| TMBOY | 47:9e361da97763 | 101 | * to use them, as they could exist and be more efficient than 32-bit on 8-bit |
| TMBOY | 47:9e361da97763 | 102 | * systems...) |
| TMBOY | 47:9e361da97763 | 103 | */ |
| TMBOY | 47:9e361da97763 | 104 | #ifndef UINT24_LEAST_MAX |
| TMBOY | 47:9e361da97763 | 105 | typedef uint_least32_t uint_least24_t; |
| TMBOY | 47:9e361da97763 | 106 | #define UINT_LEAST24_MAX UINT_LEAST32_MAX |
| TMBOY | 47:9e361da97763 | 107 | #define UINT24_C(x) UINT32_C(x) |
| TMBOY | 47:9e361da97763 | 108 | #define PRIoLEAST24 PRIoLEAST32 |
| TMBOY | 47:9e361da97763 | 109 | #define PRIuLEAST24 PRIuLEAST32 |
| TMBOY | 47:9e361da97763 | 110 | #define PRIxLEAST24 PRIxLEAST32 |
| TMBOY | 47:9e361da97763 | 111 | #define PRIXLEAST24 PRIXLEAST32 |
| TMBOY | 47:9e361da97763 | 112 | #endif |
| TMBOY | 47:9e361da97763 | 113 | |
| TMBOY | 47:9e361da97763 | 114 | #ifndef INT24_LEAST_MAX |
| TMBOY | 47:9e361da97763 | 115 | typedef int_least32_t int_least24_t; |
| TMBOY | 47:9e361da97763 | 116 | #define INT24_LEAST_MIN INT_LEAST32_MIN |
| TMBOY | 47:9e361da97763 | 117 | #define INT24_LEAST_MAX INT_LEAST32_MAX |
| TMBOY | 47:9e361da97763 | 118 | #define INT24_C(x) INT32_C(x) |
| TMBOY | 47:9e361da97763 | 119 | #define PRIdLEAST24 PRIdLEAST32 |
| TMBOY | 47:9e361da97763 | 120 | #define PRIiLEAST24 PRIiLEAST32 |
| TMBOY | 47:9e361da97763 | 121 | #endif |
| TMBOY | 47:9e361da97763 | 122 | |
| TMBOY | 47:9e361da97763 | 123 | #ifndef UINT24_FAST_MAX |
| TMBOY | 47:9e361da97763 | 124 | typedef uint_fast32_t uint_fast24_t; |
| TMBOY | 47:9e361da97763 | 125 | #define UINT_FAST24_MAX UINT_FAST32_MAX |
| TMBOY | 47:9e361da97763 | 126 | #define PRIoFAST24 PRIoFAST32 |
| TMBOY | 47:9e361da97763 | 127 | #define PRIuFAST24 PRIuFAST32 |
| TMBOY | 47:9e361da97763 | 128 | #define PRIxFAST24 PRIxFAST32 |
| TMBOY | 47:9e361da97763 | 129 | #define PRIXFAST24 PRIXFAST32 |
| TMBOY | 47:9e361da97763 | 130 | #endif |
| TMBOY | 47:9e361da97763 | 131 | |
| TMBOY | 47:9e361da97763 | 132 | #ifndef INT24_FAST_MAX |
| TMBOY | 47:9e361da97763 | 133 | typedef int_fast32_t int_fast24_t; |
| TMBOY | 47:9e361da97763 | 134 | #define INT_FAST24_MIN INT_FAST32_MIN |
| TMBOY | 47:9e361da97763 | 135 | #define INT_FAST24_MAX INT_FAST32_MAX |
| TMBOY | 47:9e361da97763 | 136 | #define PRIdFAST24 PRIdFAST32 |
| TMBOY | 47:9e361da97763 | 137 | #define PRIiFAST24 PRIiFAST32 |
| TMBOY | 47:9e361da97763 | 138 | #endif |
| TMBOY | 47:9e361da97763 | 139 | |
| TMBOY | 47:9e361da97763 | 140 | /* C11's "noreturn" macro, emulated if necessary */ |
| TMBOY | 47:9e361da97763 | 141 | #ifndef noreturn |
| TMBOY | 47:9e361da97763 | 142 | #if defined __cplusplus && __cplusplus >= 201103L |
| TMBOY | 47:9e361da97763 | 143 | // noreturn is a C++11 keyword |
| TMBOY | 47:9e361da97763 | 144 | #elif __STDC_VERSION__ >= 201112L |
| TMBOY | 47:9e361da97763 | 145 | #include <stdnoreturn.h> |
| TMBOY | 47:9e361da97763 | 146 | #elif defined __GNUC__ |
| TMBOY | 47:9e361da97763 | 147 | #define noreturn /*__attribute__((__noreturn__))*/ |
| TMBOY | 47:9e361da97763 | 148 | #elif defined __CC_ARM |
| TMBOY | 47:9e361da97763 | 149 | #define noreturn __declspec(noreturn) |
| TMBOY | 47:9e361da97763 | 150 | #elif defined __IAR_SYSTEMS_ICC__ |
| TMBOY | 47:9e361da97763 | 151 | #define noreturn __noreturn |
| TMBOY | 47:9e361da97763 | 152 | #else |
| TMBOY | 47:9e361da97763 | 153 | #define noreturn |
| TMBOY | 47:9e361da97763 | 154 | #endif |
| TMBOY | 47:9e361da97763 | 155 | #endif |
| TMBOY | 47:9e361da97763 | 156 | |
| TMBOY | 47:9e361da97763 | 157 | /* C11's "alignas" macro, emulated for integer expressions if necessary */ |
| TMBOY | 47:9e361da97763 | 158 | #ifndef __alignas_is_defined |
| TMBOY | 47:9e361da97763 | 159 | #if __STDC_VERSION__ >= 201112L || (defined __cplusplus && __cplusplus >= 201103L) |
| TMBOY | 47:9e361da97763 | 160 | #include <stdalign.h> |
| TMBOY | 47:9e361da97763 | 161 | #elif defined __GNUC__ |
| TMBOY | 47:9e361da97763 | 162 | #define alignas(n) __attribute__((__aligned__(n))) |
| TMBOY | 47:9e361da97763 | 163 | #define __alignas_is_defined 1 |
| TMBOY | 47:9e361da97763 | 164 | #elif defined __CC_ARM || defined __TASKING__ |
| TMBOY | 47:9e361da97763 | 165 | #define alignas(n) __align(n) |
| TMBOY | 47:9e361da97763 | 166 | #define __alignas_is_defined 1 |
| TMBOY | 47:9e361da97763 | 167 | #elif defined __IAR_SYSTEMS_ICC__ |
| TMBOY | 47:9e361da97763 | 168 | /* Does this really just apply to the next variable? */ |
| TMBOY | 47:9e361da97763 | 169 | #define alignas(n) __Alignas(data_alignment=n) |
| TMBOY | 47:9e361da97763 | 170 | #define __Alignas(x) _Pragma(#x) |
| TMBOY | 47:9e361da97763 | 171 | #define __alignas_is_defined 1 |
| TMBOY | 47:9e361da97763 | 172 | #endif |
| TMBOY | 47:9e361da97763 | 173 | #endif |
| TMBOY | 47:9e361da97763 | 174 | |
| TMBOY | 47:9e361da97763 | 175 | /** |
| TMBOY | 47:9e361da97763 | 176 | * Marker for functions or objects that may be unused, suppressing warnings. |
| TMBOY | 47:9e361da97763 | 177 | * Place after the identifier: |
| TMBOY | 47:9e361da97763 | 178 | * ~~~ |
| TMBOY | 47:9e361da97763 | 179 | * static int X MAYBE_UNUSED = 3; |
| TMBOY | 47:9e361da97763 | 180 | * static int foo(void) MAYBE_UNUSED; |
| TMBOY | 47:9e361da97763 | 181 | * ~~~ |
| TMBOY | 47:9e361da97763 | 182 | */ |
| TMBOY | 47:9e361da97763 | 183 | #if defined __CC_ARM || defined __GNUC__ |
| TMBOY | 47:9e361da97763 | 184 | #define MAYBE_UNUSED __attribute__((unused)) |
| TMBOY | 47:9e361da97763 | 185 | #else |
| TMBOY | 47:9e361da97763 | 186 | #define MAYBE_UNUSED |
| TMBOY | 47:9e361da97763 | 187 | #endif |
| TMBOY | 47:9e361da97763 | 188 | |
| TMBOY | 47:9e361da97763 | 189 | /* |
| TMBOY | 47:9e361da97763 | 190 | * C++ (even C++11) doesn't provide restrict: define away or provide |
| TMBOY | 47:9e361da97763 | 191 | * alternative. |
| TMBOY | 47:9e361da97763 | 192 | */ |
| TMBOY | 47:9e361da97763 | 193 | #if defined(__cplusplus) && defined(__GNUC__) |
| TMBOY | 47:9e361da97763 | 194 | #define restrict __restrict |
| TMBOY | 47:9e361da97763 | 195 | #else |
| TMBOY | 47:9e361da97763 | 196 | #define restrict |
| TMBOY | 47:9e361da97763 | 197 | #endif /* __cplusplus */ |
| TMBOY | 47:9e361da97763 | 198 | |
| TMBOY | 47:9e361da97763 | 199 | |
| TMBOY | 47:9e361da97763 | 200 | /** |
| TMBOY | 47:9e361da97763 | 201 | * C++ doesn't allow "static" in function parameter types: ie |
| TMBOY | 47:9e361da97763 | 202 | * ~~~ |
| TMBOY | 47:9e361da97763 | 203 | * entry_t *find_entry(const uint8_t address[static 16]) |
| TMBOY | 47:9e361da97763 | 204 | * ~~~ |
| TMBOY | 47:9e361da97763 | 205 | * If a header file may be included from C++, use this __static define instead. |
| TMBOY | 47:9e361da97763 | 206 | * |
| TMBOY | 47:9e361da97763 | 207 | * (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always |
| TMBOY | 47:9e361da97763 | 208 | * equivalent to `uint8_t *address`, but the C99 addition of static tells the |
| TMBOY | 47:9e361da97763 | 209 | * compiler that address is never NULL, and always points to at least 16 |
| TMBOY | 47:9e361da97763 | 210 | * elements. This adds no new type-checking, but the information could aid |
| TMBOY | 47:9e361da97763 | 211 | * compiler optimisation, and it can serve as documentation). |
| TMBOY | 47:9e361da97763 | 212 | */ |
| TMBOY | 47:9e361da97763 | 213 | #ifdef __cplusplus |
| TMBOY | 47:9e361da97763 | 214 | #define __static |
| TMBOY | 47:9e361da97763 | 215 | #else |
| TMBOY | 47:9e361da97763 | 216 | #define __static static |
| TMBOY | 47:9e361da97763 | 217 | #endif |
| TMBOY | 47:9e361da97763 | 218 | |
| TMBOY | 47:9e361da97763 | 219 | #ifdef __GNUC__ |
| TMBOY | 47:9e361da97763 | 220 | #define NS_GCC_VERSION (__GNUC__ * 10000 \ |
| TMBOY | 47:9e361da97763 | 221 | + __GNUC_MINOR__ * 100 \ |
| TMBOY | 47:9e361da97763 | 222 | + __GNUC_PATCHLEVEL__) |
| TMBOY | 47:9e361da97763 | 223 | #endif |
| TMBOY | 47:9e361da97763 | 224 | |
| TMBOY | 47:9e361da97763 | 225 | /** \brief Compile-time assertion |
| TMBOY | 47:9e361da97763 | 226 | * |
| TMBOY | 47:9e361da97763 | 227 | * C11 provides _Static_assert, as does GCC even in C99 or C++ mode (and |
| TMBOY | 47:9e361da97763 | 228 | * as a freestanding implementation, we can't rely on <assert.h> to get |
| TMBOY | 47:9e361da97763 | 229 | * the static_assert macro). |
| TMBOY | 47:9e361da97763 | 230 | * C++11 provides static_assert as a keyword. |
| TMBOY | 47:9e361da97763 | 231 | * |
| TMBOY | 47:9e361da97763 | 232 | * The assertion acts as a declaration that can be placed at file scope, in a |
| TMBOY | 47:9e361da97763 | 233 | * code block (except after a label), or as a member of a struct/union. It |
| TMBOY | 47:9e361da97763 | 234 | * produces a compiler error if "test" evaluates to 0. |
| TMBOY | 47:9e361da97763 | 235 | * |
| TMBOY | 47:9e361da97763 | 236 | * Note that this *includes* the required semicolon when defined, else it |
| TMBOY | 47:9e361da97763 | 237 | * is totally empty, permitting use in structs. (If the user provided the `;`, |
| TMBOY | 47:9e361da97763 | 238 | * it would leave an illegal stray `;` if unavailable). |
| TMBOY | 47:9e361da97763 | 239 | */ |
| TMBOY | 47:9e361da97763 | 240 | #if __STDC_VERSION__ >= 201112L |
| TMBOY | 47:9e361da97763 | 241 | #define NS_STATIC_ASSERT(test, str) _Static_assert(test, str); |
| TMBOY | 47:9e361da97763 | 242 | #elif defined __cplusplus && __cplusplus >= 201103L |
| TMBOY | 47:9e361da97763 | 243 | #define NS_STATIC_ASSERT(test, str) static_assert(test, str); |
| TMBOY | 47:9e361da97763 | 244 | #elif defined __GNUC__ && NS_GCC_VERSION >= 40600 |
| TMBOY | 47:9e361da97763 | 245 | //#define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str); |
| TMBOY | 47:9e361da97763 | 246 | #define NS_STATIC_ASSERT(test, str) |
| TMBOY | 47:9e361da97763 | 247 | #else |
| TMBOY | 47:9e361da97763 | 248 | #define NS_STATIC_ASSERT(test, str) |
| TMBOY | 47:9e361da97763 | 249 | #endif |
| TMBOY | 47:9e361da97763 | 250 | |
| TMBOY | 47:9e361da97763 | 251 | #define static_assert _Static_assert |
| TMBOY | 47:9e361da97763 | 252 | |
| TMBOY | 47:9e361da97763 | 253 | /** \brief Pragma to suppress warnings about unusual pointer values. |
| TMBOY | 47:9e361da97763 | 254 | * |
| TMBOY | 47:9e361da97763 | 255 | * Useful if using "poison" values. |
| TMBOY | 47:9e361da97763 | 256 | */ |
| TMBOY | 47:9e361da97763 | 257 | #ifdef __IAR_SYSTEMS_ICC__ |
| TMBOY | 47:9e361da97763 | 258 | #define NS_FUNNY_INTPTR_OK _Pragma("diag_suppress=Pe1053") |
| TMBOY | 47:9e361da97763 | 259 | #define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053") |
| TMBOY | 47:9e361da97763 | 260 | #else |
| TMBOY | 47:9e361da97763 | 261 | #define NS_FUNNY_INTPTR_OK |
| TMBOY | 47:9e361da97763 | 262 | #define NS_FUNNY_INTPTR_RESTORE |
| TMBOY | 47:9e361da97763 | 263 | #endif |
| TMBOY | 47:9e361da97763 | 264 | |
| TMBOY | 47:9e361da97763 | 265 | /** \brief Convert pointer to member to pointer to containing structure */ |
| TMBOY | 47:9e361da97763 | 266 | #define NS_CONTAINER_OF(ptr, type, member) \ |
| TMBOY | 47:9e361da97763 | 267 | ((type *) ((char *) (ptr) - offsetof(type, member))) |
| TMBOY | 47:9e361da97763 | 268 | |
| TMBOY | 47:9e361da97763 | 269 | /* |
| TMBOY | 47:9e361da97763 | 270 | * Inlining could cause problems when mixing with C++; provide a mechanism to |
| TMBOY | 47:9e361da97763 | 271 | * disable it. This could also be turned off for other reasons (although |
| TMBOY | 47:9e361da97763 | 272 | * this can usually be done through a compiler flag, eg -O0 on gcc). |
| TMBOY | 47:9e361da97763 | 273 | */ |
| TMBOY | 47:9e361da97763 | 274 | #ifndef __cplusplus |
| TMBOY | 47:9e361da97763 | 275 | #define NS_ALLOW_INLINING |
| TMBOY | 47:9e361da97763 | 276 | #endif |
| TMBOY | 47:9e361da97763 | 277 | |
| TMBOY | 47:9e361da97763 | 278 | /* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */ |
| TMBOY | 47:9e361da97763 | 279 | #if defined __GNUC__ && NS_GCC_VERSION < 40600 |
| TMBOY | 47:9e361da97763 | 280 | #undef NS_ALLOW_INLINING |
| TMBOY | 47:9e361da97763 | 281 | #endif |
| TMBOY | 47:9e361da97763 | 282 | |
| TMBOY | 47:9e361da97763 | 283 | /** \brief Mark a potentially-inlineable function. |
| TMBOY | 47:9e361da97763 | 284 | * |
| TMBOY | 47:9e361da97763 | 285 | * We follow C99 semantics, which requires precisely one external definition. |
| TMBOY | 47:9e361da97763 | 286 | * To also allow inlining to be totally bypassed under control of |
| TMBOY | 47:9e361da97763 | 287 | * NS_ALLOW_INLINING, code can be structured as per the example of ns_list: |
| TMBOY | 47:9e361da97763 | 288 | * |
| TMBOY | 47:9e361da97763 | 289 | * foo.h |
| TMBOY | 47:9e361da97763 | 290 | * ----- |
| TMBOY | 47:9e361da97763 | 291 | * ~~~ |
| TMBOY | 47:9e361da97763 | 292 | * NS_INLINE int my_func(int); |
| TMBOY | 47:9e361da97763 | 293 | * |
| TMBOY | 47:9e361da97763 | 294 | * #if defined NS_ALLOW_INLINING || defined FOO_FN |
| TMBOY | 47:9e361da97763 | 295 | * #ifndef FOO_FN |
| TMBOY | 47:9e361da97763 | 296 | * #define FOO_FN NS_INLINE |
| TMBOY | 47:9e361da97763 | 297 | * #endif |
| TMBOY | 47:9e361da97763 | 298 | * FOO_FN int my_func(int a) |
| TMBOY | 47:9e361da97763 | 299 | * { |
| TMBOY | 47:9e361da97763 | 300 | * definition; |
| TMBOY | 47:9e361da97763 | 301 | * } |
| TMBOY | 47:9e361da97763 | 302 | * #endif |
| TMBOY | 47:9e361da97763 | 303 | * ~~~ |
| TMBOY | 47:9e361da97763 | 304 | * foo.c |
| TMBOY | 47:9e361da97763 | 305 | * ----- |
| TMBOY | 47:9e361da97763 | 306 | * ~~~ |
| TMBOY | 47:9e361da97763 | 307 | * #define FOO_FN extern |
| TMBOY | 47:9e361da97763 | 308 | * #include "foo.h" |
| TMBOY | 47:9e361da97763 | 309 | * ~~~ |
| TMBOY | 47:9e361da97763 | 310 | * Which generates: |
| TMBOY | 47:9e361da97763 | 311 | * ~~~ |
| TMBOY | 47:9e361da97763 | 312 | * NS_ALLOW_INLINING set NS_ALLOW_INLINING unset |
| TMBOY | 47:9e361da97763 | 313 | * ===================== ======================= |
| TMBOY | 47:9e361da97763 | 314 | * Include foo.h Include foo.h |
| TMBOY | 47:9e361da97763 | 315 | * ------------- ------------- |
| TMBOY | 47:9e361da97763 | 316 | * inline int my_func(int); int my_func(int); |
| TMBOY | 47:9e361da97763 | 317 | * |
| TMBOY | 47:9e361da97763 | 318 | * // inline definition |
| TMBOY | 47:9e361da97763 | 319 | * inline int my_func(int a) |
| TMBOY | 47:9e361da97763 | 320 | * { |
| TMBOY | 47:9e361da97763 | 321 | * definition; |
| TMBOY | 47:9e361da97763 | 322 | * } |
| TMBOY | 47:9e361da97763 | 323 | * |
| TMBOY | 47:9e361da97763 | 324 | * Compile foo.c Compile foo.c |
| TMBOY | 47:9e361da97763 | 325 | * ------------- ------------- |
| TMBOY | 47:9e361da97763 | 326 | * (from .h) inline int my_func(int); int my_func(int); |
| TMBOY | 47:9e361da97763 | 327 | * |
| TMBOY | 47:9e361da97763 | 328 | * // external definition |
| TMBOY | 47:9e361da97763 | 329 | * // because of no "inline" // normal external definition |
| TMBOY | 47:9e361da97763 | 330 | * extern int my_func(int a) extern int my_func(int a) |
| TMBOY | 47:9e361da97763 | 331 | * { { |
| TMBOY | 47:9e361da97763 | 332 | * definition; definition; |
| TMBOY | 47:9e361da97763 | 333 | * } } |
| TMBOY | 47:9e361da97763 | 334 | * ~~~ |
| TMBOY | 47:9e361da97763 | 335 | * |
| TMBOY | 47:9e361da97763 | 336 | * Note that even with inline keywords, whether the compiler inlines or not is |
| TMBOY | 47:9e361da97763 | 337 | * up to it. For example, gcc at "-O0" will not inline at all, and will always |
| TMBOY | 47:9e361da97763 | 338 | * call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset. |
| TMBOY | 47:9e361da97763 | 339 | * At "-O2", gcc could potentially inline everything, meaning that foo.o is not |
| TMBOY | 47:9e361da97763 | 340 | * referenced at all. |
| TMBOY | 47:9e361da97763 | 341 | * |
| TMBOY | 47:9e361da97763 | 342 | * Alternatively, you could use "static inline", which gives every caller its |
| TMBOY | 47:9e361da97763 | 343 | * own internal definition. This is compatible with C++ inlining (which expects |
| TMBOY | 47:9e361da97763 | 344 | * the linker to eliminate duplicates), but in C it's less efficient if the code |
| TMBOY | 47:9e361da97763 | 345 | * ends up non-inlined, and it's harder to breakpoint. I don't recommend it |
| TMBOY | 47:9e361da97763 | 346 | * except for the most trivial functions (which could then probably be macros). |
| TMBOY | 47:9e361da97763 | 347 | */ |
| TMBOY | 47:9e361da97763 | 348 | #ifdef NS_ALLOW_INLINING |
| TMBOY | 47:9e361da97763 | 349 | #define NS_INLINE inline |
| TMBOY | 47:9e361da97763 | 350 | #else |
| TMBOY | 47:9e361da97763 | 351 | #define NS_INLINE |
| TMBOY | 47:9e361da97763 | 352 | #endif |
| TMBOY | 47:9e361da97763 | 353 | |
| TMBOY | 47:9e361da97763 | 354 | #if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__ |
| TMBOY | 47:9e361da97763 | 355 | |
| TMBOY | 47:9e361da97763 | 356 | /* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */ |
| TMBOY | 47:9e361da97763 | 357 | |
| TMBOY | 47:9e361da97763 | 358 | #define NS_LARGE __xdata |
| TMBOY | 47:9e361da97763 | 359 | #define NS_LARGE_PTR __xdata |
| TMBOY | 47:9e361da97763 | 360 | #ifdef __ICC8051__ |
| TMBOY | 47:9e361da97763 | 361 | #define NS_REENTRANT |
| TMBOY | 47:9e361da97763 | 362 | #define NS_REENTRANT_PREFIX __idata_reentrant |
| TMBOY | 47:9e361da97763 | 363 | #else |
| TMBOY | 47:9e361da97763 | 364 | #define NS_REENTRANT __reentrant |
| TMBOY | 47:9e361da97763 | 365 | #define NS_REENTRANT_PREFIX |
| TMBOY | 47:9e361da97763 | 366 | #endif |
| TMBOY | 47:9e361da97763 | 367 | #define NS_NEAR_FUNC __near_func |
| TMBOY | 47:9e361da97763 | 368 | |
| TMBOY | 47:9e361da97763 | 369 | #else |
| TMBOY | 47:9e361da97763 | 370 | |
| TMBOY | 47:9e361da97763 | 371 | /* "Normal" systems. Define it all away. */ |
| TMBOY | 47:9e361da97763 | 372 | #define NS_LARGE |
| TMBOY | 47:9e361da97763 | 373 | #define NS_LARGE_PTR |
| TMBOY | 47:9e361da97763 | 374 | #define NS_REENTRANT |
| TMBOY | 47:9e361da97763 | 375 | #define NS_REENTRANT_PREFIX |
| TMBOY | 47:9e361da97763 | 376 | #define NS_NEAR_FUNC |
| TMBOY | 47:9e361da97763 | 377 | |
| TMBOY | 47:9e361da97763 | 378 | #endif |
| TMBOY | 47:9e361da97763 | 379 | |
| TMBOY | 47:9e361da97763 | 380 | /** \brief Scatter-gather descriptor |
| TMBOY | 47:9e361da97763 | 381 | * |
| TMBOY | 47:9e361da97763 | 382 | * Slightly optimised for small platforms - we assume we won't need any |
| TMBOY | 47:9e361da97763 | 383 | * element bigger than 64K. |
| TMBOY | 47:9e361da97763 | 384 | */ |
| TMBOY | 47:9e361da97763 | 385 | typedef struct ns_iovec |
| TMBOY | 47:9e361da97763 | 386 | { |
| TMBOY | 47:9e361da97763 | 387 | void *iov_base; |
| TMBOY | 47:9e361da97763 | 388 | uint_fast16_t iov_len; |
| TMBOY | 47:9e361da97763 | 389 | } ns_iovec_t; |
| TMBOY | 47:9e361da97763 | 390 | #endif /* NS_TYPES_H */ |
