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.

/media/uploads/hudakz/enc28j60_module01.jpg

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" to main.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.

Committer:
hudakz
Date:
Sat Sep 07 17:42:42 2019 +0000
Revision:
15:53715cc81c63
Parent:
14:7648334eb41b
Timeout parameter added for the 'connect' function, SPI speed reduced from 20 to 10 Mb/s, debug messages fixed ...

Who changed what in which revision?

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