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
Library for ENC28J60 Ethernet modules.
Ported to mbed from Norbert Truchsess's UIPEthernet library for Arduino. Thank you Norbert!
- Full support for persistent (streaming) TCP/IP and UDP connections Client and Server each, ARP, ICMP, DHCP and DNS.
- Works with both Mbed OS 2 and Mbed OS 5.
Usage:
- Import the library into your project.
- Add
#include "UipEthernet.h"
tomain.cpp
- Create one instance of the UipEthernet class initialized with the MAC address you'd like to use and SPI pins of the connected Mbed board.
Example programs:
Import programWebSwitch_ENC28J60
HTTP Server serving a simple webpage which enables to remotely turn a digital output on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.
Import programHTTPServer_Echo_ENC28J60
A simple HTTP server echoing received requests. Ethernet connection is over an ENC28J60 board. Usage: Type the server's IP address into you web browser and hit <ENTER>.
Import programTcpServer_ENC28J60
Simple TCP/IP Server using the UIPEthernet library for ENC28J60 Ethernet boards.
Import programTcpClient_ENC28J60
Simple TCP/IP Client using the UIPEthernet library for ENC28J60 Ethernet boards.
Import programUdpServer_ENC28J60
Simple UDP Server using the UIPEthernet library for ENC28J60 Ethernet boards.
Import programUdpClient_ENC28J60
Simple UDP Client using the UIPEthernet library for ENC28J60 Ethernet boards.
Import programMQTT_Hello_ENC28J60
MQTT Client example program. Ethernet connection is via an ENC28J60 module.
utility/ns_types.h@18:8d5738a6646e, 2020-07-23 (annotated)
- Committer:
- hudakz
- Date:
- Thu Jul 23 15:30:54 2020 +0000
- Revision:
- 18:8d5738a6646e
- Parent:
- 14:7648334eb41b
Mbed library for ENC28J60 Ethernet modules.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hudakz | 14:7648334eb41b | 1 | /* |
hudakz | 14:7648334eb41b | 2 | * Copyright (c) 2014-2015 ARM Limited. All rights reserved. |
hudakz | 14:7648334eb41b | 3 | * SPDX-License-Identifier: Apache-2.0 |
hudakz | 14:7648334eb41b | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
hudakz | 14:7648334eb41b | 5 | * not use this file except in compliance with the License. |
hudakz | 14:7648334eb41b | 6 | * You may obtain a copy of the License at |
hudakz | 14:7648334eb41b | 7 | * |
hudakz | 14:7648334eb41b | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
hudakz | 14:7648334eb41b | 9 | * |
hudakz | 14:7648334eb41b | 10 | * Unless required by applicable law or agreed to in writing, software |
hudakz | 14:7648334eb41b | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
hudakz | 14:7648334eb41b | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
hudakz | 14:7648334eb41b | 13 | * See the License for the specific language governing permissions and |
hudakz | 14:7648334eb41b | 14 | * limitations under the License. |
hudakz | 14:7648334eb41b | 15 | */ |
hudakz | 14:7648334eb41b | 16 | /* |
hudakz | 14:7648334eb41b | 17 | * ns_types.h - Basic compiler and type setup for Nanostack libraries. |
hudakz | 14:7648334eb41b | 18 | */ |
hudakz | 14:7648334eb41b | 19 | #ifndef NS_TYPES_H_ |
hudakz | 14:7648334eb41b | 20 | #define NS_TYPES_H_ |
hudakz | 14:7648334eb41b | 21 | |
hudakz | 14:7648334eb41b | 22 | /** \file |
hudakz | 14:7648334eb41b | 23 | * \brief Basic compiler and type setup |
hudakz | 14:7648334eb41b | 24 | * |
hudakz | 14:7648334eb41b | 25 | * We currently assume C99 or later. |
hudakz | 14:7648334eb41b | 26 | * |
hudakz | 14:7648334eb41b | 27 | * C99 features being relied on: |
hudakz | 14:7648334eb41b | 28 | * |
hudakz | 14:7648334eb41b | 29 | * - <inttypes.h> and <stdbool.h> |
hudakz | 14:7648334eb41b | 30 | * - inline (with C99 semantics, not C++ as per default GCC); |
hudakz | 14:7648334eb41b | 31 | * - designated initialisers; |
hudakz | 14:7648334eb41b | 32 | * - compound literals; |
hudakz | 14:7648334eb41b | 33 | * - restrict; |
hudakz | 14:7648334eb41b | 34 | * - [static N] in array parameters; |
hudakz | 14:7648334eb41b | 35 | * - declarations in for statements; |
hudakz | 14:7648334eb41b | 36 | * - mixing declarations and statements |
hudakz | 14:7648334eb41b | 37 | * |
hudakz | 14:7648334eb41b | 38 | * Compilers should be set to C99 or later mode when building Nanomesh source. |
hudakz | 14:7648334eb41b | 39 | * For GCC this means "-std=gnu99" (C99 with usual GNU extensions). |
hudakz | 14:7648334eb41b | 40 | * |
hudakz | 14:7648334eb41b | 41 | * Also, a little extra care is required for public header files that could be |
hudakz | 14:7648334eb41b | 42 | * included from C++, especially as C++ lacks some C99 features. |
hudakz | 14:7648334eb41b | 43 | * |
hudakz | 14:7648334eb41b | 44 | * (TODO: as this is exposed to API users, do we need a predefine to distinguish |
hudakz | 14:7648334eb41b | 45 | * internal and external use, for finer control? Not yet, but maybe...) |
hudakz | 14:7648334eb41b | 46 | */ |
hudakz | 14:7648334eb41b | 47 | |
hudakz | 14:7648334eb41b | 48 | /* Make sure <stdint.h> defines its macros if C++ */ |
hudakz | 14:7648334eb41b | 49 | #ifndef __STDC_LIMIT_MACROS |
hudakz | 14:7648334eb41b | 50 | #define __STDC_LIMIT_MACROS |
hudakz | 14:7648334eb41b | 51 | #endif |
hudakz | 14:7648334eb41b | 52 | #ifndef __STDC_CONSTANT_MACROS |
hudakz | 14:7648334eb41b | 53 | #define __STDC_CONSTANT_MACROS |
hudakz | 14:7648334eb41b | 54 | #endif |
hudakz | 14:7648334eb41b | 55 | |
hudakz | 14:7648334eb41b | 56 | #include <stddef.h> |
hudakz | 14:7648334eb41b | 57 | #include <inttypes.h> // includes <stdint.h>; debugf() users need PRIu32 etc |
hudakz | 14:7648334eb41b | 58 | #include <stdbool.h> |
hudakz | 14:7648334eb41b | 59 | |
hudakz | 14:7648334eb41b | 60 | /* |
hudakz | 14:7648334eb41b | 61 | * Create the optional <stdint.h> 24-bit types if they don't exist (worth trying |
hudakz | 14:7648334eb41b | 62 | * to use them, as they could exist and be more efficient than 32-bit on 8-bit |
hudakz | 14:7648334eb41b | 63 | * systems...) |
hudakz | 14:7648334eb41b | 64 | */ |
hudakz | 14:7648334eb41b | 65 | #ifndef UINT_LEAST24_MAX |
hudakz | 14:7648334eb41b | 66 | typedef uint_least32_t uint_least24_t; |
hudakz | 14:7648334eb41b | 67 | #define UINT_LEAST24_MAX UINT_LEAST32_MAX |
hudakz | 14:7648334eb41b | 68 | #define UINT24_C(x) UINT32_C(x) |
hudakz | 14:7648334eb41b | 69 | #define PRIoLEAST24 PRIoLEAST32 |
hudakz | 14:7648334eb41b | 70 | #define PRIuLEAST24 PRIuLEAST32 |
hudakz | 14:7648334eb41b | 71 | #define PRIxLEAST24 PRIxLEAST32 |
hudakz | 14:7648334eb41b | 72 | #define PRIXLEAST24 PRIXLEAST32 |
hudakz | 14:7648334eb41b | 73 | #endif |
hudakz | 14:7648334eb41b | 74 | |
hudakz | 14:7648334eb41b | 75 | #ifndef INT_LEAST24_MAX |
hudakz | 14:7648334eb41b | 76 | typedef int_least32_t int_least24_t; |
hudakz | 14:7648334eb41b | 77 | #define INT_LEAST24_MIN INT_LEAST32_MIN |
hudakz | 14:7648334eb41b | 78 | #define INT_LEAST24_MAX INT_LEAST32_MAX |
hudakz | 14:7648334eb41b | 79 | #define INT24_C(x) INT32_C(x) |
hudakz | 14:7648334eb41b | 80 | #define PRIdLEAST24 PRIdLEAST32 |
hudakz | 14:7648334eb41b | 81 | #define PRIiLEAST24 PRIiLEAST32 |
hudakz | 14:7648334eb41b | 82 | #endif |
hudakz | 14:7648334eb41b | 83 | |
hudakz | 14:7648334eb41b | 84 | #ifndef UINT_FAST24_MAX |
hudakz | 14:7648334eb41b | 85 | typedef uint_fast32_t uint_fast24_t; |
hudakz | 14:7648334eb41b | 86 | #define UINT_FAST24_MAX UINT_FAST32_MAX |
hudakz | 14:7648334eb41b | 87 | #define PRIoFAST24 PRIoFAST32 |
hudakz | 14:7648334eb41b | 88 | #define PRIuFAST24 PRIuFAST32 |
hudakz | 14:7648334eb41b | 89 | #define PRIxFAST24 PRIxFAST32 |
hudakz | 14:7648334eb41b | 90 | #define PRIXFAST24 PRIXFAST32 |
hudakz | 14:7648334eb41b | 91 | #endif |
hudakz | 14:7648334eb41b | 92 | |
hudakz | 14:7648334eb41b | 93 | #ifndef INT_FAST24_MAX |
hudakz | 14:7648334eb41b | 94 | typedef int_fast32_t int_fast24_t; |
hudakz | 14:7648334eb41b | 95 | #define INT_FAST24_MIN INT_FAST32_MIN |
hudakz | 14:7648334eb41b | 96 | #define INT_FAST24_MAX INT_FAST32_MAX |
hudakz | 14:7648334eb41b | 97 | #define PRIdFAST24 PRIdFAST32 |
hudakz | 14:7648334eb41b | 98 | #define PRIiFAST24 PRIiFAST32 |
hudakz | 14:7648334eb41b | 99 | #endif |
hudakz | 14:7648334eb41b | 100 | |
hudakz | 14:7648334eb41b | 101 | /* Function attribute - C11 "noreturn" or C++11 "[[noreturn]]" */ |
hudakz | 14:7648334eb41b | 102 | #ifndef NS_NORETURN |
hudakz | 14:7648334eb41b | 103 | #if defined __cplusplus && __cplusplus >= 201103L |
hudakz | 14:7648334eb41b | 104 | #define NS_NORETURN [[noreturn]] |
hudakz | 14:7648334eb41b | 105 | #elif !defined __cplusplus && __STDC_VERSION__ >= 201112L |
hudakz | 14:7648334eb41b | 106 | #define NS_NORETURN _Noreturn |
hudakz | 14:7648334eb41b | 107 | #elif defined __GNUC__ |
hudakz | 14:7648334eb41b | 108 | #define NS_NORETURN __attribute__((__noreturn__)) |
hudakz | 14:7648334eb41b | 109 | #elif defined __CC_ARM |
hudakz | 14:7648334eb41b | 110 | #define NS_NORETURN __declspec(noreturn) |
hudakz | 14:7648334eb41b | 111 | #elif defined __IAR_SYSTEMS_ICC__ |
hudakz | 14:7648334eb41b | 112 | #define NS_NORETURN __noreturn |
hudakz | 14:7648334eb41b | 113 | #else |
hudakz | 14:7648334eb41b | 114 | #define NS_NORETURN |
hudakz | 14:7648334eb41b | 115 | #endif |
hudakz | 14:7648334eb41b | 116 | #endif |
hudakz | 14:7648334eb41b | 117 | |
hudakz | 14:7648334eb41b | 118 | /* C11's "alignas" macro, emulated for integer expressions if necessary */ |
hudakz | 14:7648334eb41b | 119 | #ifndef __alignas_is_defined |
hudakz | 14:7648334eb41b | 120 | #if defined __CC_ARM || defined __TASKING__ |
hudakz | 14:7648334eb41b | 121 | #define alignas(n) __align(n) |
hudakz | 14:7648334eb41b | 122 | #define __alignas_is_defined 1 |
hudakz | 14:7648334eb41b | 123 | #elif (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L) || (defined __cplusplus && __cplusplus >= 201103L) |
hudakz | 14:7648334eb41b | 124 | # if defined __ARMCC_VERSION && __ARMCC_VERSION < 6120000 |
hudakz | 14:7648334eb41b | 125 | /* Workaround for Arm Compiler versions prior to 6.12 */ |
hudakz | 14:7648334eb41b | 126 | # if !defined __cplusplus |
hudakz | 14:7648334eb41b | 127 | # define alignas _Alignas |
hudakz | 14:7648334eb41b | 128 | # endif |
hudakz | 14:7648334eb41b | 129 | # define __alignas_is_defined 1 |
hudakz | 14:7648334eb41b | 130 | # else |
hudakz | 14:7648334eb41b | 131 | # include <stdalign.h> |
hudakz | 14:7648334eb41b | 132 | # endif |
hudakz | 14:7648334eb41b | 133 | #elif defined __GNUC__ |
hudakz | 14:7648334eb41b | 134 | #define alignas(n) __attribute__((__aligned__(n))) |
hudakz | 14:7648334eb41b | 135 | #define __alignas_is_defined 1 |
hudakz | 14:7648334eb41b | 136 | #elif defined __IAR_SYSTEMS_ICC__ |
hudakz | 14:7648334eb41b | 137 | /* Does this really just apply to the next variable? */ |
hudakz | 14:7648334eb41b | 138 | #define alignas(n) __Alignas(data_alignment=n) |
hudakz | 14:7648334eb41b | 139 | #define __Alignas(x) _Pragma(#x) |
hudakz | 14:7648334eb41b | 140 | #define __alignas_is_defined 1 |
hudakz | 14:7648334eb41b | 141 | #endif |
hudakz | 14:7648334eb41b | 142 | #endif |
hudakz | 14:7648334eb41b | 143 | |
hudakz | 14:7648334eb41b | 144 | /** |
hudakz | 14:7648334eb41b | 145 | * Marker for functions or objects that may be unused, suppressing warnings. |
hudakz | 14:7648334eb41b | 146 | * Place after the identifier: |
hudakz | 14:7648334eb41b | 147 | * ~~~ |
hudakz | 14:7648334eb41b | 148 | * static int X MAYBE_UNUSED = 3; |
hudakz | 14:7648334eb41b | 149 | * static int foo(void) MAYBE_UNUSED; |
hudakz | 14:7648334eb41b | 150 | * ~~~ |
hudakz | 14:7648334eb41b | 151 | */ |
hudakz | 14:7648334eb41b | 152 | #if defined __CC_ARM || defined __GNUC__ |
hudakz | 14:7648334eb41b | 153 | #define MAYBE_UNUSED __attribute__((unused)) |
hudakz | 14:7648334eb41b | 154 | #else |
hudakz | 14:7648334eb41b | 155 | #define MAYBE_UNUSED |
hudakz | 14:7648334eb41b | 156 | #endif |
hudakz | 14:7648334eb41b | 157 | |
hudakz | 14:7648334eb41b | 158 | /* |
hudakz | 14:7648334eb41b | 159 | * C++ (even C++11) doesn't provide restrict: define away or provide |
hudakz | 14:7648334eb41b | 160 | * alternative. |
hudakz | 14:7648334eb41b | 161 | */ |
hudakz | 14:7648334eb41b | 162 | #ifdef __cplusplus |
hudakz | 14:7648334eb41b | 163 | #ifdef __GNUC__ |
hudakz | 14:7648334eb41b | 164 | #define restrict __restrict |
hudakz | 14:7648334eb41b | 165 | #else |
hudakz | 14:7648334eb41b | 166 | #define restrict |
hudakz | 14:7648334eb41b | 167 | #endif |
hudakz | 14:7648334eb41b | 168 | #endif /* __cplusplus */ |
hudakz | 14:7648334eb41b | 169 | |
hudakz | 14:7648334eb41b | 170 | |
hudakz | 14:7648334eb41b | 171 | /** |
hudakz | 14:7648334eb41b | 172 | * C++ doesn't allow "static" in function parameter types: ie |
hudakz | 14:7648334eb41b | 173 | * ~~~ |
hudakz | 14:7648334eb41b | 174 | * entry_t *find_entry(const uint8_t address[static 16]) |
hudakz | 14:7648334eb41b | 175 | * ~~~ |
hudakz | 14:7648334eb41b | 176 | * If a header file may be included from C++, use this __static define instead. |
hudakz | 14:7648334eb41b | 177 | * |
hudakz | 14:7648334eb41b | 178 | * (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always |
hudakz | 14:7648334eb41b | 179 | * equivalent to `uint8_t *address`, but the C99 addition of static tells the |
hudakz | 14:7648334eb41b | 180 | * compiler that address is never NULL, and always points to at least 16 |
hudakz | 14:7648334eb41b | 181 | * elements. This adds no new type-checking, but the information could aid |
hudakz | 14:7648334eb41b | 182 | * compiler optimisation, and it can serve as documentation). |
hudakz | 14:7648334eb41b | 183 | */ |
hudakz | 14:7648334eb41b | 184 | #ifdef __cplusplus |
hudakz | 14:7648334eb41b | 185 | #define __static |
hudakz | 14:7648334eb41b | 186 | #else |
hudakz | 14:7648334eb41b | 187 | #define __static static |
hudakz | 14:7648334eb41b | 188 | #endif |
hudakz | 14:7648334eb41b | 189 | |
hudakz | 14:7648334eb41b | 190 | #ifdef __GNUC__ |
hudakz | 14:7648334eb41b | 191 | #define NS_GCC_VERSION (__GNUC__ * 10000 \ |
hudakz | 14:7648334eb41b | 192 | + __GNUC_MINOR__ * 100 \ |
hudakz | 14:7648334eb41b | 193 | + __GNUC_PATCHLEVEL__) |
hudakz | 14:7648334eb41b | 194 | #endif |
hudakz | 14:7648334eb41b | 195 | |
hudakz | 14:7648334eb41b | 196 | /** \brief Compile-time assertion |
hudakz | 14:7648334eb41b | 197 | * |
hudakz | 14:7648334eb41b | 198 | * C11 provides _Static_assert, as does GCC even in C99 mode (and |
hudakz | 14:7648334eb41b | 199 | * as a freestanding implementation, we can't rely on <assert.h> to get |
hudakz | 14:7648334eb41b | 200 | * the static_assert macro). |
hudakz | 14:7648334eb41b | 201 | * C++11 provides static_assert as a keyword, as does G++ in C++0x mode. |
hudakz | 14:7648334eb41b | 202 | * |
hudakz | 14:7648334eb41b | 203 | * The assertion acts as a declaration that can be placed at file scope, in a |
hudakz | 14:7648334eb41b | 204 | * code block (except after a label), or as a member of a struct/union. It |
hudakz | 14:7648334eb41b | 205 | * produces a compiler error if "test" evaluates to 0. |
hudakz | 14:7648334eb41b | 206 | * |
hudakz | 14:7648334eb41b | 207 | * Note that this *includes* the required semicolon when defined, else it |
hudakz | 14:7648334eb41b | 208 | * is totally empty, permitting use in structs. (If the user provided the `;`, |
hudakz | 14:7648334eb41b | 209 | * it would leave an illegal stray `;` if unavailable). |
hudakz | 14:7648334eb41b | 210 | */ |
hudakz | 14:7648334eb41b | 211 | #ifdef __cplusplus |
hudakz | 14:7648334eb41b | 212 | # if __cplusplus >= 201103L || __cpp_static_assert >= 200410 |
hudakz | 14:7648334eb41b | 213 | # define NS_STATIC_ASSERT(test, str) static_assert(test, str); |
hudakz | 14:7648334eb41b | 214 | # elif defined __GXX_EXPERIMENTAL_CXX0X__ && NS_GCC_VERSION >= 40300 |
hudakz | 14:7648334eb41b | 215 | # define NS_STATIC_ASSERT(test, str) __extension__ static_assert(test, str); |
hudakz | 14:7648334eb41b | 216 | # else |
hudakz | 14:7648334eb41b | 217 | # define NS_STATIC_ASSERT(test, str) |
hudakz | 14:7648334eb41b | 218 | # endif |
hudakz | 14:7648334eb41b | 219 | #else /* C */ |
hudakz | 14:7648334eb41b | 220 | # if __STDC_VERSION__ >= 201112L |
hudakz | 14:7648334eb41b | 221 | # define NS_STATIC_ASSERT(test, str) _Static_assert(test, str); |
hudakz | 14:7648334eb41b | 222 | # elif defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM |
hudakz | 14:7648334eb41b | 223 | # ifdef _Static_assert |
hudakz | 14:7648334eb41b | 224 | /* |
hudakz | 14:7648334eb41b | 225 | * Some versions of glibc cdefs.h (which comes in via <stdint.h> above) |
hudakz | 14:7648334eb41b | 226 | * attempt to define their own _Static_assert (if GCC < 4.6 or |
hudakz | 14:7648334eb41b | 227 | * __STRICT_ANSI__) using an extern declaration, which doesn't work in a |
hudakz | 14:7648334eb41b | 228 | * struct/union. |
hudakz | 14:7648334eb41b | 229 | * |
hudakz | 14:7648334eb41b | 230 | * For GCC >= 4.6 and __STRICT_ANSI__, we can do better - just use |
hudakz | 14:7648334eb41b | 231 | * the built-in _Static_assert with __extension__. We have to do this, as |
hudakz | 14:7648334eb41b | 232 | * ns_list.h needs to use it in a union. No way to get at it though, without |
hudakz | 14:7648334eb41b | 233 | * overriding their define. |
hudakz | 14:7648334eb41b | 234 | */ |
hudakz | 14:7648334eb41b | 235 | # undef _Static_assert |
hudakz | 14:7648334eb41b | 236 | # define _Static_assert(x, y) __extension__ _Static_assert(x, y) |
hudakz | 14:7648334eb41b | 237 | # endif |
hudakz | 14:7648334eb41b | 238 | # define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str); |
hudakz | 14:7648334eb41b | 239 | # else |
hudakz | 14:7648334eb41b | 240 | # define NS_STATIC_ASSERT(test, str) |
hudakz | 14:7648334eb41b | 241 | #endif |
hudakz | 14:7648334eb41b | 242 | #endif |
hudakz | 14:7648334eb41b | 243 | |
hudakz | 14:7648334eb41b | 244 | /** \brief Pragma to suppress warnings about unusual pointer values. |
hudakz | 14:7648334eb41b | 245 | * |
hudakz | 14:7648334eb41b | 246 | * Useful if using "poison" values. |
hudakz | 14:7648334eb41b | 247 | */ |
hudakz | 14:7648334eb41b | 248 | #ifdef __IAR_SYSTEMS_ICC__ |
hudakz | 14:7648334eb41b | 249 | #define NS_FUNNY_INTPTR_OK _Pragma("diag_suppress=Pe1053") |
hudakz | 14:7648334eb41b | 250 | #define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053") |
hudakz | 14:7648334eb41b | 251 | #else |
hudakz | 14:7648334eb41b | 252 | #define NS_FUNNY_INTPTR_OK |
hudakz | 14:7648334eb41b | 253 | #define NS_FUNNY_INTPTR_RESTORE |
hudakz | 14:7648334eb41b | 254 | #endif |
hudakz | 14:7648334eb41b | 255 | |
hudakz | 14:7648334eb41b | 256 | /** \brief Pragma to suppress warnings about always true/false comparisons |
hudakz | 14:7648334eb41b | 257 | */ |
hudakz | 14:7648334eb41b | 258 | #if defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM |
hudakz | 14:7648334eb41b | 259 | #define NS_FUNNY_COMPARE_OK _Pragma("GCC diagnostic push") \ |
hudakz | 14:7648334eb41b | 260 | _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") |
hudakz | 14:7648334eb41b | 261 | #define NS_FUNNY_COMPARE_RESTORE _Pragma("GCC diagnostic pop") |
hudakz | 14:7648334eb41b | 262 | #else |
hudakz | 14:7648334eb41b | 263 | #define NS_FUNNY_COMPARE_OK |
hudakz | 14:7648334eb41b | 264 | #define NS_FUNNY_COMPARE_RESTORE |
hudakz | 14:7648334eb41b | 265 | #endif |
hudakz | 14:7648334eb41b | 266 | |
hudakz | 14:7648334eb41b | 267 | /** \brief Pragma to suppress warnings arising from dummy definitions. |
hudakz | 14:7648334eb41b | 268 | * |
hudakz | 14:7648334eb41b | 269 | * Useful when you have function-like macros that returning constants |
hudakz | 14:7648334eb41b | 270 | * in cut-down builds. Can be fairly cavalier about disabling as we |
hudakz | 14:7648334eb41b | 271 | * do not expect every build to use this macro. Generic builds of |
hudakz | 14:7648334eb41b | 272 | * components should ensure this is not included by only using it in |
hudakz | 14:7648334eb41b | 273 | * a ifdef blocks providing dummy definitions. |
hudakz | 14:7648334eb41b | 274 | */ |
hudakz | 14:7648334eb41b | 275 | #ifdef __CC_ARM |
hudakz | 14:7648334eb41b | 276 | // statement is unreachable(111), controlling expression is constant(236), expression has no effect(174), |
hudakz | 14:7648334eb41b | 277 | // function was declared but never referenced(177), variable was set but never used(550) |
hudakz | 14:7648334eb41b | 278 | #define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=111,236,174,177,550") |
hudakz | 14:7648334eb41b | 279 | #elif defined __IAR_SYSTEMS_ICC__ |
hudakz | 14:7648334eb41b | 280 | // controlling expression is constant |
hudakz | 14:7648334eb41b | 281 | #define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=Pe236") |
hudakz | 14:7648334eb41b | 282 | #else |
hudakz | 14:7648334eb41b | 283 | #define NS_DUMMY_DEFINITIONS_OK |
hudakz | 14:7648334eb41b | 284 | #endif |
hudakz | 14:7648334eb41b | 285 | |
hudakz | 14:7648334eb41b | 286 | /** \brief Convert pointer to member to pointer to containing structure */ |
hudakz | 14:7648334eb41b | 287 | #define NS_CONTAINER_OF(ptr, type, member) \ |
hudakz | 14:7648334eb41b | 288 | ((type *) ((char *) (ptr) - offsetof(type, member))) |
hudakz | 14:7648334eb41b | 289 | |
hudakz | 14:7648334eb41b | 290 | /* |
hudakz | 14:7648334eb41b | 291 | * Inlining could cause problems when mixing with C++; provide a mechanism to |
hudakz | 14:7648334eb41b | 292 | * disable it. This could also be turned off for other reasons (although |
hudakz | 14:7648334eb41b | 293 | * this can usually be done through a compiler flag, eg -O0 on gcc). |
hudakz | 14:7648334eb41b | 294 | */ |
hudakz | 14:7648334eb41b | 295 | #ifndef __cplusplus |
hudakz | 14:7648334eb41b | 296 | #define NS_ALLOW_INLINING |
hudakz | 14:7648334eb41b | 297 | #endif |
hudakz | 14:7648334eb41b | 298 | |
hudakz | 14:7648334eb41b | 299 | /* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */ |
hudakz | 14:7648334eb41b | 300 | #if defined __GNUC__ && NS_GCC_VERSION < 40600 |
hudakz | 14:7648334eb41b | 301 | #undef NS_ALLOW_INLINING |
hudakz | 14:7648334eb41b | 302 | #endif |
hudakz | 14:7648334eb41b | 303 | |
hudakz | 14:7648334eb41b | 304 | /** \brief Mark a potentially-inlineable function. |
hudakz | 14:7648334eb41b | 305 | * |
hudakz | 14:7648334eb41b | 306 | * We follow C99 semantics, which requires precisely one external definition. |
hudakz | 14:7648334eb41b | 307 | * To also allow inlining to be totally bypassed under control of |
hudakz | 14:7648334eb41b | 308 | * NS_ALLOW_INLINING, code can be structured as per the example of ns_list: |
hudakz | 14:7648334eb41b | 309 | * |
hudakz | 14:7648334eb41b | 310 | * foo.h |
hudakz | 14:7648334eb41b | 311 | * ----- |
hudakz | 14:7648334eb41b | 312 | * ~~~ |
hudakz | 14:7648334eb41b | 313 | * NS_INLINE int my_func(int); |
hudakz | 14:7648334eb41b | 314 | * |
hudakz | 14:7648334eb41b | 315 | * #if defined NS_ALLOW_INLINING || defined FOO_FN |
hudakz | 14:7648334eb41b | 316 | * #ifndef FOO_FN |
hudakz | 14:7648334eb41b | 317 | * #define FOO_FN NS_INLINE |
hudakz | 14:7648334eb41b | 318 | * #endif |
hudakz | 14:7648334eb41b | 319 | * FOO_FN int my_func(int a) |
hudakz | 14:7648334eb41b | 320 | * { |
hudakz | 14:7648334eb41b | 321 | * definition; |
hudakz | 14:7648334eb41b | 322 | * } |
hudakz | 14:7648334eb41b | 323 | * #endif |
hudakz | 14:7648334eb41b | 324 | * ~~~ |
hudakz | 14:7648334eb41b | 325 | * foo.c |
hudakz | 14:7648334eb41b | 326 | * ----- |
hudakz | 14:7648334eb41b | 327 | * ~~~ |
hudakz | 14:7648334eb41b | 328 | * #define FOO_FN extern |
hudakz | 14:7648334eb41b | 329 | * #include "foo.h" |
hudakz | 14:7648334eb41b | 330 | * ~~~ |
hudakz | 14:7648334eb41b | 331 | * Which generates: |
hudakz | 14:7648334eb41b | 332 | * ~~~ |
hudakz | 14:7648334eb41b | 333 | * NS_ALLOW_INLINING set NS_ALLOW_INLINING unset |
hudakz | 14:7648334eb41b | 334 | * ===================== ======================= |
hudakz | 14:7648334eb41b | 335 | * Include foo.h Include foo.h |
hudakz | 14:7648334eb41b | 336 | * ------------- ------------- |
hudakz | 14:7648334eb41b | 337 | * inline int my_func(int); int my_func(int); |
hudakz | 14:7648334eb41b | 338 | * |
hudakz | 14:7648334eb41b | 339 | * // inline definition |
hudakz | 14:7648334eb41b | 340 | * inline int my_func(int a) |
hudakz | 14:7648334eb41b | 341 | * { |
hudakz | 14:7648334eb41b | 342 | * definition; |
hudakz | 14:7648334eb41b | 343 | * } |
hudakz | 14:7648334eb41b | 344 | * |
hudakz | 14:7648334eb41b | 345 | * Compile foo.c Compile foo.c |
hudakz | 14:7648334eb41b | 346 | * ------------- ------------- |
hudakz | 14:7648334eb41b | 347 | * (from .h) inline int my_func(int); int my_func(int); |
hudakz | 14:7648334eb41b | 348 | * |
hudakz | 14:7648334eb41b | 349 | * // external definition |
hudakz | 14:7648334eb41b | 350 | * // because of no "inline" // normal external definition |
hudakz | 14:7648334eb41b | 351 | * extern int my_func(int a) extern int my_func(int a) |
hudakz | 14:7648334eb41b | 352 | * { { |
hudakz | 14:7648334eb41b | 353 | * definition; definition; |
hudakz | 14:7648334eb41b | 354 | * } } |
hudakz | 14:7648334eb41b | 355 | * ~~~ |
hudakz | 14:7648334eb41b | 356 | * |
hudakz | 14:7648334eb41b | 357 | * Note that even with inline keywords, whether the compiler inlines or not is |
hudakz | 14:7648334eb41b | 358 | * up to it. For example, gcc at "-O0" will not inline at all, and will always |
hudakz | 14:7648334eb41b | 359 | * call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset. |
hudakz | 14:7648334eb41b | 360 | * At "-O2", gcc could potentially inline everything, meaning that foo.o is not |
hudakz | 14:7648334eb41b | 361 | * referenced at all. |
hudakz | 14:7648334eb41b | 362 | * |
hudakz | 14:7648334eb41b | 363 | * Alternatively, you could use "static inline", which gives every caller its |
hudakz | 14:7648334eb41b | 364 | * own internal definition. This is compatible with C++ inlining (which expects |
hudakz | 14:7648334eb41b | 365 | * the linker to eliminate duplicates), but in C it's less efficient if the code |
hudakz | 14:7648334eb41b | 366 | * ends up non-inlined, and it's harder to breakpoint. I don't recommend it |
hudakz | 14:7648334eb41b | 367 | * except for the most trivial functions (which could then probably be macros). |
hudakz | 14:7648334eb41b | 368 | */ |
hudakz | 14:7648334eb41b | 369 | #ifdef NS_ALLOW_INLINING |
hudakz | 14:7648334eb41b | 370 | #define NS_INLINE inline |
hudakz | 14:7648334eb41b | 371 | #else |
hudakz | 14:7648334eb41b | 372 | #define NS_INLINE |
hudakz | 14:7648334eb41b | 373 | #endif |
hudakz | 14:7648334eb41b | 374 | |
hudakz | 14:7648334eb41b | 375 | #if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__ |
hudakz | 14:7648334eb41b | 376 | |
hudakz | 14:7648334eb41b | 377 | /* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */ |
hudakz | 14:7648334eb41b | 378 | |
hudakz | 14:7648334eb41b | 379 | #define NS_LARGE __xdata |
hudakz | 14:7648334eb41b | 380 | #define NS_LARGE_PTR __xdata |
hudakz | 14:7648334eb41b | 381 | #ifdef __ICC8051__ |
hudakz | 14:7648334eb41b | 382 | #define NS_REENTRANT |
hudakz | 14:7648334eb41b | 383 | #define NS_REENTRANT_PREFIX __idata_reentrant |
hudakz | 14:7648334eb41b | 384 | #else |
hudakz | 14:7648334eb41b | 385 | #define NS_REENTRANT __reentrant |
hudakz | 14:7648334eb41b | 386 | #define NS_REENTRANT_PREFIX |
hudakz | 14:7648334eb41b | 387 | #endif |
hudakz | 14:7648334eb41b | 388 | #define NS_NEAR_FUNC __near_func |
hudakz | 14:7648334eb41b | 389 | |
hudakz | 14:7648334eb41b | 390 | #else |
hudakz | 14:7648334eb41b | 391 | |
hudakz | 14:7648334eb41b | 392 | /* "Normal" systems. Define it all away. */ |
hudakz | 14:7648334eb41b | 393 | #define NS_LARGE |
hudakz | 14:7648334eb41b | 394 | #define NS_LARGE_PTR |
hudakz | 14:7648334eb41b | 395 | #define NS_REENTRANT |
hudakz | 14:7648334eb41b | 396 | #define NS_REENTRANT_PREFIX |
hudakz | 14:7648334eb41b | 397 | #define NS_NEAR_FUNC |
hudakz | 14:7648334eb41b | 398 | |
hudakz | 14:7648334eb41b | 399 | #endif |
hudakz | 14:7648334eb41b | 400 | |
hudakz | 14:7648334eb41b | 401 | /** \brief Scatter-gather descriptor |
hudakz | 14:7648334eb41b | 402 | * |
hudakz | 14:7648334eb41b | 403 | * Slightly optimised for small platforms - we assume we won't need any |
hudakz | 14:7648334eb41b | 404 | * element bigger than 64K. |
hudakz | 14:7648334eb41b | 405 | */ |
hudakz | 14:7648334eb41b | 406 | typedef struct ns_iovec { |
hudakz | 14:7648334eb41b | 407 | void *iov_base; |
hudakz | 14:7648334eb41b | 408 | uint_fast16_t iov_len; |
hudakz | 14:7648334eb41b | 409 | } ns_iovec_t; |
hudakz | 14:7648334eb41b | 410 | |
hudakz | 14:7648334eb41b | 411 | #endif /* NS_TYPES_H */ |