mbed client lightswitch demo
Dependencies: mbed Socket lwip-eth lwip-sys lwip
Fork of mbed-client-classic-example-lwip by
Diff: nanostack-libservice/mbed-client-libservice/ns_types.h
- Revision:
- 11:cada08fc8a70
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nanostack-libservice/mbed-client-libservice/ns_types.h Thu Jun 09 17:08:36 2016 +0000
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * ns_types.h - Basic compiler and type setup for Nanostack libraries.
+ */
+#ifndef NS_TYPES_H_
+#define NS_TYPES_H_
+
+/** \file
+ * \brief Basic compiler and type setup
+ *
+ * We currently assume C99 or later.
+ *
+ * C99 features being relied on:
+ *
+ * - <inttypes.h> and <stdbool.h>
+ * - inline (with C99 semantics, not C++ as per default GCC);
+ * - designated initialisers;
+ * - compound literals;
+ * - restrict;
+ * - [static N] in array parameters;
+ * - declarations in for statements;
+ * - mixing declarations and statements
+ *
+ * Compilers should be set to C99 or later mode when building Nanomesh source.
+ * For GCC this means "-std=gnu99" (C99 with usual GNU extensions).
+ *
+ * Also, a little extra care is required for public header files that could be
+ * included from C++, especially as C++ lacks some C99 features.
+ *
+ * (TODO: as this is exposed to API users, do we need a predefine to distinguish
+ * internal and external use, for finer control? Not yet, but maybe...)
+ */
+
+/* Make sure <stdint.h> defines its macros if C++ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+#include <stddef.h>
+#include <inttypes.h> // includes <stdint.h>; debugf() users need PRIu32 etc
+#include <stdbool.h>
+
+/*
+ * Create the optional <stdint.h> 24-bit types if they don't exist (worth trying
+ * to use them, as they could exist and be more efficient than 32-bit on 8-bit
+ * systems...)
+ */
+#ifndef UINT24_LEAST_MAX
+typedef uint_least32_t uint_least24_t;
+#define UINT_LEAST24_MAX UINT_LEAST32_MAX
+#define UINT24_C(x) UINT32_C(x)
+#define PRIoLEAST24 PRIoLEAST32
+#define PRIuLEAST24 PRIuLEAST32
+#define PRIxLEAST24 PRIxLEAST32
+#define PRIXLEAST24 PRIXLEAST32
+#endif
+
+#ifndef INT24_LEAST_MAX
+typedef int_least32_t int_least24_t;
+#define INT24_LEAST_MIN INT_LEAST32_MIN
+#define INT24_LEAST_MAX INT_LEAST32_MAX
+#define INT24_C(x) INT32_C(x)
+#define PRIdLEAST24 PRIdLEAST32
+#define PRIiLEAST24 PRIiLEAST32
+#endif
+
+#ifndef UINT24_FAST_MAX
+typedef uint_fast32_t uint_fast24_t;
+#define UINT_FAST24_MAX UINT_FAST32_MAX
+#define PRIoFAST24 PRIoFAST32
+#define PRIuFAST24 PRIuFAST32
+#define PRIxFAST24 PRIxFAST32
+#define PRIXFAST24 PRIXFAST32
+#endif
+
+#ifndef INT24_FAST_MAX
+typedef int_fast32_t int_fast24_t;
+#define INT_FAST24_MIN INT_FAST32_MIN
+#define INT_FAST24_MAX INT_FAST32_MAX
+#define PRIdFAST24 PRIdFAST32
+#define PRIiFAST24 PRIiFAST32
+#endif
+
+/* Function attribute - C11 "noreturn" or C++11 "[[noreturn]]" */
+#ifndef NS_NORETURN
+#if defined __cplusplus && __cplusplus >= 201103L
+#define NS_NORETURN [[noreturn]]
+#elif !defined __cplusplus && __STDC_VERSION__ >= 201112L
+#define NS_NORETURN _Noreturn
+#elif defined __GNUC__
+#define NS_NORETURN __attribute__((__noreturn__))
+#elif defined __CC_ARM
+#define NS_NORETURN __declspec(noreturn)
+#elif defined __IAR_SYSTEMS_ICC__
+#define NS_NORETURN __noreturn
+#else
+#define NS_NORETURN
+#endif
+#endif
+
+/* C11's "alignas" macro, emulated for integer expressions if necessary */
+#ifndef __alignas_is_defined
+#if __STDC_VERSION__ >= 201112L || (defined __cplusplus && __cplusplus >= 201103L)
+#include <stdalign.h>
+#elif defined __GNUC__
+#define alignas(n) __attribute__((__aligned__(n)))
+#define __alignas_is_defined 1
+#elif defined __CC_ARM || defined __TASKING__
+#define alignas(n) __align(n)
+#define __alignas_is_defined 1
+#elif defined __IAR_SYSTEMS_ICC__
+/* Does this really just apply to the next variable? */
+#define alignas(n) __Alignas(data_alignment=n)
+#define __Alignas(x) _Pragma(#x)
+#define __alignas_is_defined 1
+#endif
+#endif
+
+/**
+ * Marker for functions or objects that may be unused, suppressing warnings.
+ * Place after the identifier:
+ * ~~~
+ * static int X MAYBE_UNUSED = 3;
+ * static int foo(void) MAYBE_UNUSED;
+ * ~~~
+ */
+#if defined __CC_ARM || defined __GNUC__
+#define MAYBE_UNUSED __attribute__((unused))
+#else
+#define MAYBE_UNUSED
+#endif
+
+/*
+ * C++ (even C++11) doesn't provide restrict: define away or provide
+ * alternative.
+ */
+#ifdef __cplusplus
+#ifdef __GNUC__
+#define restrict __restrict
+#else
+#define restrict
+#endif
+#endif /* __cplusplus */
+
+
+/**
+ * C++ doesn't allow "static" in function parameter types: ie
+ * ~~~
+ * entry_t *find_entry(const uint8_t address[static 16])
+ * ~~~
+ * If a header file may be included from C++, use this __static define instead.
+ *
+ * (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always
+ * equivalent to `uint8_t *address`, but the C99 addition of static tells the
+ * compiler that address is never NULL, and always points to at least 16
+ * elements. This adds no new type-checking, but the information could aid
+ * compiler optimisation, and it can serve as documentation).
+ */
+#ifdef __cplusplus
+#define __static
+#else
+#define __static static
+#endif
+
+#ifdef __GNUC__
+#define NS_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+#endif
+
+/** \brief Compile-time assertion
+ *
+ * C11 provides _Static_assert, as does GCC even in C99 mode (and
+ * as a freestanding implementation, we can't rely on <assert.h> to get
+ * the static_assert macro).
+ * C++11 provides static_assert as a keyword, as does G++ in C++0x mode.
+ *
+ * The assertion acts as a declaration that can be placed at file scope, in a
+ * code block (except after a label), or as a member of a struct/union. It
+ * produces a compiler error if "test" evaluates to 0.
+ *
+ * Note that this *includes* the required semicolon when defined, else it
+ * is totally empty, permitting use in structs. (If the user provided the `;`,
+ * it would leave an illegal stray `;` if unavailable).
+ */
+#ifdef __cplusplus
+# if __cplusplus >= 201103L || __cpp_static_assert >= 200410
+# define NS_STATIC_ASSERT(test, str) static_assert(test, str);
+# elif defined __GXX_EXPERIMENTAL_CXX0X__ && NS_GCC_VERSION >= 40300
+# define NS_STATIC_ASSERT(test, str) __extension__ static_assert(test, str);
+# else
+# define NS_STATIC_ASSERT(test, str)
+# endif
+#else /* C */
+# if __STDC_VERSION__ >= 201112L
+# define NS_STATIC_ASSERT(test, str) _Static_assert(test, str);
+# elif defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM
+# define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str);
+# else
+# define NS_STATIC_ASSERT(test, str)
+#endif
+#endif
+
+/** \brief Pragma to suppress warnings about unusual pointer values.
+ *
+ * Useful if using "poison" values.
+ */
+#ifdef __IAR_SYSTEMS_ICC__
+#define NS_FUNNY_INTPTR_OK _Pragma("diag_suppress=Pe1053")
+#define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053")
+#else
+#define NS_FUNNY_INTPTR_OK
+#define NS_FUNNY_INTPTR_RESTORE
+#endif
+
+/** \brief Convert pointer to member to pointer to containing structure */
+#define NS_CONTAINER_OF(ptr, type, member) \
+ ((type *) ((char *) (ptr) - offsetof(type, member)))
+
+/*
+ * Inlining could cause problems when mixing with C++; provide a mechanism to
+ * disable it. This could also be turned off for other reasons (although
+ * this can usually be done through a compiler flag, eg -O0 on gcc).
+ */
+#ifndef __cplusplus
+#define NS_ALLOW_INLINING
+#endif
+
+/* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */
+#if defined __GNUC__ && NS_GCC_VERSION < 40600
+#undef NS_ALLOW_INLINING
+#endif
+
+/** \brief Mark a potentially-inlineable function.
+ *
+ * We follow C99 semantics, which requires precisely one external definition.
+ * To also allow inlining to be totally bypassed under control of
+ * NS_ALLOW_INLINING, code can be structured as per the example of ns_list:
+ *
+ * foo.h
+ * -----
+ * ~~~
+ * NS_INLINE int my_func(int);
+ *
+ * #if defined NS_ALLOW_INLINING || defined FOO_FN
+ * #ifndef FOO_FN
+ * #define FOO_FN NS_INLINE
+ * #endif
+ * FOO_FN int my_func(int a)
+ * {
+ * definition;
+ * }
+ * #endif
+ * ~~~
+ * foo.c
+ * -----
+ * ~~~
+ * #define FOO_FN extern
+ * #include "foo.h"
+ * ~~~
+ * Which generates:
+ * ~~~
+ * NS_ALLOW_INLINING set NS_ALLOW_INLINING unset
+ * ===================== =======================
+ * Include foo.h Include foo.h
+ * ------------- -------------
+ * inline int my_func(int); int my_func(int);
+ *
+ * // inline definition
+ * inline int my_func(int a)
+ * {
+ * definition;
+ * }
+ *
+ * Compile foo.c Compile foo.c
+ * ------------- -------------
+ * (from .h) inline int my_func(int); int my_func(int);
+ *
+ * // external definition
+ * // because of no "inline" // normal external definition
+ * extern int my_func(int a) extern int my_func(int a)
+ * { {
+ * definition; definition;
+ * } }
+ * ~~~
+ *
+ * Note that even with inline keywords, whether the compiler inlines or not is
+ * up to it. For example, gcc at "-O0" will not inline at all, and will always
+ * call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset.
+ * At "-O2", gcc could potentially inline everything, meaning that foo.o is not
+ * referenced at all.
+ *
+ * Alternatively, you could use "static inline", which gives every caller its
+ * own internal definition. This is compatible with C++ inlining (which expects
+ * the linker to eliminate duplicates), but in C it's less efficient if the code
+ * ends up non-inlined, and it's harder to breakpoint. I don't recommend it
+ * except for the most trivial functions (which could then probably be macros).
+ */
+#ifdef NS_ALLOW_INLINING
+#define NS_INLINE inline
+#else
+#define NS_INLINE
+#endif
+
+#if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__
+
+/* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */
+
+#define NS_LARGE __xdata
+#define NS_LARGE_PTR __xdata
+#ifdef __ICC8051__
+#define NS_REENTRANT
+#define NS_REENTRANT_PREFIX __idata_reentrant
+#else
+#define NS_REENTRANT __reentrant
+#define NS_REENTRANT_PREFIX
+#endif
+#define NS_NEAR_FUNC __near_func
+
+#else
+
+/* "Normal" systems. Define it all away. */
+#define NS_LARGE
+#define NS_LARGE_PTR
+#define NS_REENTRANT
+#define NS_REENTRANT_PREFIX
+#define NS_NEAR_FUNC
+
+#endif
+
+/** \brief Scatter-gather descriptor
+ *
+ * Slightly optimised for small platforms - we assume we won't need any
+ * element bigger than 64K.
+ */
+typedef struct ns_iovec {
+ void *iov_base;
+ uint_fast16_t iov_len;
+} ns_iovec_t;
+
+#endif /* NS_TYPES_H */
Austin Blackstone
