Arduino LMIC 6.0.1
Arduino LoRaWAN(r) MAC in C
Loading...
Searching...
No Matches
lmic_env.h
1/*
2
3Module: lmic_env.h
4
5Function:
6 Sets up macros etc. to make things a little easier for portabilty
7
8Copyright notice and license info:
9 See LICENSE file accompanying this project.
10
11Author:
12 Terry Moore, MCCI Corporation November 2018
13
14Description:
15 This file is an adaptation of MCCI's standard IOCTL framework.
16 We duplicate a bit of functionality that we might get from other
17 libraries, so that the LMIC library can continue to stand alone.
18
19*/
20
21#ifndef _lmic_env_h_ /* prevent multiple includes */
22#define _lmic_env_h_
23
24/*
25
26Macro: LMIC_C_ASSERT()
27
28Function:
29 Declaration-like macro that will cause a compile error if arg is FALSE.
30
31Definition:
32 LMIC_C_ASSERT(
33 BOOL fErrorIfFalse
34 );
35
36Description:
37 This macro, if used where an external reference declarataion is
38 permitted, will either compile cleanly, or will cause a compilation
39 error. The results of using this macro where a declaration is not
40 permitted are unspecified.
41
42 This is different from #if !(fErrorIfFalse) / #error in that the
43 expression is evaluated by the compiler rather than by the pre-
44 processor. Therefore things like sizeof() can be used.
45
46Returns:
47 No explicit result -- either compiles cleanly or causes a compile
48 error.
49
50*/
51
52#ifndef LMIC_C_ASSERT
53# define LMIC_C_ASSERT(e) \
54 void LMIC_C_ASSERT__(int LMIC_C_ASSERT_x[(e) ? 1: -1])
55#endif
56
57/****************************************************************************\
58|
59| Define the begin/end declaration tags for C++ co-existance
60|
61\****************************************************************************/
62
63#ifdef __cplusplus
64# define LMIC_BEGIN_DECLS extern "C" {
65# define LMIC_END_DECLS }
66#else
67# define LMIC_BEGIN_DECLS /* nothing */
68# define LMIC_END_DECLS /* nothing */
69#endif
70
71//----------------------------------------------------------------------------
72// Annotations to avoid various "unused" warnings. These must appear as a
73// statement in the function body; the macro annotates the variable to quiet
74// compiler warnings. The way this is done is compiler-specific, and so these
75// definitions are fall-backs, which might be overridden.
76//
77// Although these are all similar, we don't want extra macro expansions,
78// so we define each one explicitly rather than relying on a common macro.
79//----------------------------------------------------------------------------
80
81// signal that a parameter is intentionally unused.
82#ifndef LMIC_UNREFERENCED_PARAMETER
83# define LMIC_UNREFERENCED_PARAMETER(v) do { (void) (v); } while (0)
84#endif
85
86// an API parameter is a parameter that is required by an API definition, but
87// happens to be unreferenced in this implementation. This is a stronger
88// assertion than LMIC_UNREFERENCED_PARAMETER(): this parameter is here
89// becuase of an API contract, but we have no use for it in this function.
90#ifndef LMIC_API_PARAMETER
91# define LMIC_API_PARAMETER(v) do { (void) (v); } while (0)
92#endif
93
94// an intentionally-unreferenced variable.
95#ifndef LMIC_UNREFERENCED_VARIABLE
96# define LMIC_UNREFERENCED_VARIABLE(v) do { (void) (v); } while (0)
97#endif
98
99// we have three (!) debug levels (LMIC_DEBUG_LEVEL > 0, LMIC_DEBUG_LEVEL > 1,
100// and LMIC_X_DEBUG_LEVEL > 0. In each case we might have parameters or
101// or varables that are only refereneced at the target debug level.
102
103// Parameter referenced only if debugging at level > 0.
104#ifndef LMIC_DEBUG1_PARAMETER
105# if LMIC_DEBUG_LEVEL > 0
106# define LMIC_DEBUG1_PARAMETER(v) do { ; } while (0)
107# else
108# define LMIC_DEBUG1_PARAMETER(v) do { (void) (v); } while (0)
109# endif
110#endif
111
112// variable referenced only if debugging at level > 0
113#ifndef LMIC_DEBUG1_VARIABLE
114# if LMIC_DEBUG_LEVEL > 0
115# define LMIC_DEBUG1_VARIABLE(v) do { ; } while (0)
116# else
117# define LMIC_DEBUG1_VARIABLE(v) do { (void) (v); } while (0)
118# endif
119#endif
120
121// parameter referenced only if debugging at level > 1
122#ifndef LMIC_DEBUG2_PARAMETER
123# if LMIC_DEBUG_LEVEL > 1
124# define LMIC_DEBUG2_PARAMETER(v) do { ; } while (0)
125# else
126# define LMIC_DEBUG2_PARAMETER(v) do { (void) (v); } while (0)
127# endif
128#endif
129
130// variable referenced only if debugging at level > 1
131#ifndef LMIC_DEBUG2_VARIABLE
132# if LMIC_DEBUG_LEVEL > 1
133# define LMIC_DEBUG2_VARIABLE(v) do { ; } while (0)
134# else
135# define LMIC_DEBUG2_VARIABLE(v) do { (void) (v); } while (0)
136# endif
137#endif
138
139// parameter referenced only if LMIC_X_DEBUG_LEVEL > 0
140#ifndef LMIC_X_DEBUG_PARAMETER
141# if LMIC_X_DEBUG_LEVEL > 0
142# define LMIC_X_DEBUG_PARAMETER(v) do { ; } while (0)
143# else
144# define LMIC_X_DEBUG_PARAMETER(v) do { (void) (v); } while (0)
145# endif
146#endif
147
148// variable referenced only if LMIC_X_DEBUG_LEVEL > 0
149#ifndef LMIC_X_DEBUG_VARIABLE
150# if LMIC_X_DEBUG_LEVEL > 0
151# define LMIC_X_DEBUG_VARIABLE(v) do { ; } while (0)
152# else
153# define LMIC_X_DEBUG_VARIABLE(v) do { (void) (v); } while (0)
154# endif
155#endif
156
157// parameter referenced only if EV() macro is enabled (which it never is)
158// TODO(tmm@mcci.com) take out the EV() framework as it requires C++, and
159// this code is really C-99 to its bones.
160#ifndef LMIC_EV_PARAMETER
161# define LMIC_EV_PARAMETER(v) do { (void) (v); } while (0)
162#endif
163
164// variable referenced only if EV() macro is defined.
165#ifndef LMIC_EV_VARIABLE
166# define LMIC_EV_VARIABLE(v) do { (void) (v); } while (0)
167#endif
168
169␌/*
170
171Macro: LMIC_ABI_STD
172
173Index: Macro: LMIC_ABI_VARARGS
174
175Function:
176 Annotation macros to force a particular binary calling sequence.
177
178Definition:
179 #define LMIC_ABI_STD compiler-specific
180 #define LMIC_ABI_VARARGS compiler-specific
181
182Description:
183 These macros are used when declaring a function type, and indicate
184 that a particular calling sequence is to be used. They are normally
185 used between the type portion of the function declaration and the
186 name of the function. For example:
187
188 typedef void LMIC_ABI_STD myCallBack_t(void);
189
190 It's important to use this in libraries on platforms with multiple
191 calling sequences, because different components can be compiled with
192 different defaults.
193
194Returns:
195 Not applicable.
196
197*/
198
199/* ABI marker for normal (fixed parameter count) functions -- used for function types */
200#ifndef LMIC_ABI_STD
201# ifdef _MSC_VER
202# define LMIC_ABI_STD __stdcall
203# else
204# define LMIC_ABI_STD /* nothing */
205# endif
206#endif
207
208/* ABI marker for VARARG functions -- used for function types */
209#ifndef LMIC_ABI_VARARGS
210# ifdef _MSC_VER
211# define LMIC_ABI_VARARGS __cdecl
212# else
213# define LMIC_ABI_VARARGS /* nothing */
214# endif
215#endif
216
217/*
218
219Macro: LMIC_DECLARE_FUNCTION_WEAK()
220
221Function:
222 Declare an external function as a weak reference.
223
224Definition:
225 #define LMIC_DECLARE_FUNCTION_WEAK(ReturnType, FunctionName, Params) ...
226
227Description:
228 This macro generates a weak reference to the specified function.
229
230Example:
231 LMIC_DECLARE_FUNCTION_WEAK(void, onEvent, (ev_t e));
232
233 This saya that onEvent is a weak external reference. When calling
234 onEvent, you must always first check whether it's supplied:
235
236 if (onEvent != NULL)
237 onEvent(e);
238
239Returns:
240 This macro expands to a declaration, without a trailing semicolon.
241
242Notes:
243 This form allows for compilers that use _Pragma(weak, name) instead
244 of inline attributes.
245
246*/
247
248#define LMIC_DECLARE_FUNCTION_WEAK(a_ReturnType, a_FunctionName, a_Params) \
249 a_ReturnType __attribute__((__weak__)) a_FunctionName a_Params
250
251/*
252
253Macro: ARDUINO_LMIC_VERSION_CALC()
254
255Index: Macro: ARDUINO_LMIC_VERSION_GET_MAJOR()
256 Macro: ARDUINO_LMIC_VERSION_GET_MINOR()
257 Macro: ARDUINO_LMIC_VERSION_GET_PATCH()
258 Macro: ARDUINO_LMIC_VERSION_GET_PRE()
259 Macro: ARDUINO_LMIC_VERSION_GET_LOCAL() (deprecated)
260 Macro: ARDUINO_LMIC_VERSION_TO_ORDINAL()
261 Macro: ARDUINO_LMIC_VERSION_COMPARE_LT()
262 Macro: ARDUINO_LMIC_VERSION_COMPARE_LE()
263 Macro: ARDUINO_LMIC_VERSION_COMPARE_GT()
264 Macro: ARDUINO_LMIC_VERSION_COMPARE_GE()
265
266Function:
267 LMIC semantic version calculations.
268
269Definition:
270 #define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, pre) ...
271 #define ARDUINO_LMIC_VERSION_GET_MAJOR(version_uint32) ...
272 #define ARDUINO_LMIC_VERSION_GET_MINOR(version_uint32) ...
273 #define ARDUINO_LMIC_VERSION_GET_PATCH(version_uint32) ...
274 #define ARDUINO_LMIC_VERSION_GET_PRE(version_uint32) ...
275 #define ARDUINO_LMIC_VERSION_GET_LOCAL(version_uint32) ... (deprecated)
276 #define ARDUINO_LMIC_VERSION_TO_ORDINAL(version_uint32) ...
277 #define ARDUINO_LMIC_VERSION_COMPARE_LT(version1, version2) ...
278 #define ARDUINO_LMIC_VERSION_COMPARE_LE(version1, version2) ...
279 #define ARDUINO_LMIC_VERSION_COMPARE_GT(version1, version2) ...
280 #define ARDUINO_LMIC_VERSION_COMPARE_GE(version1, version2) ...
281
282Description:
283 These macros are used for creating and manipulating semantic version
284 constants.
285
286 SemanticVersions according to https://semver.org/v2 have
287 up to four parts: major, minor, patch, and pre-release. If a semantic
288 version string has a pre-release, it sorts before the equivalent
289 version string without a pre-release; otherwise version strings sort
290 lexicographically.
291
292 To make compile time operations easier, we limit the four fields to
293 eight bits. The fourth field, `pre`, is the pre-release number; if
294 non-zero, the version is a pre-release.
295
296 To avoid confusion, we represent the version fields in a uint32_t,
297 exactly as given. However, this means that the versions can't
298 be sorted directly because the 32-bit numbers corresponding to
299 pre-releases are greater than the 32-bit number representing the
300 final release.
301
302 To ease comparisons, ARDUINO_LMIC_VERSION_TO_ORDINAL() turns a
303 direct representation of the four fields into a uint32_t which
304 can be compared to any other version ordinal using normal integer
305 comparisons. The four comparison macros use this macro to
306 return a boolean result.
307
308 All these macros can be used at compile time.
309
310Returns:
311 ARDUINO_LMIC_VERSION_CALC() returns a 32-bit version number.
312 ARDUINO_LMIC_VERSION_GET_MAJOR(), MINOR(), PATCH(), and PRE()
313 return an 8-bit number extracted from the corresponding field.
314 ARDUINO_LMIC_VERSION_TO_ORDINAL() returns a 32-bit ordinal.
315 ARDUINO_LMIC_VERSION_COMPARE_LT(), LE(), GT(), GE() return
316 booleans.
317
318Notes:
319 ARDUINO_LMIC_VERSION_GET_LOCAL() is the historical name for
320 ARDUINO_LMIC_VERSION_GET_PRE(). It still works, but using it
321 produces a deprecation warning on GCC 6 and later and on Clang.
322
323 The standard way to format versions is:
324
325 {major}.{minor}.{patch}[-pre{pre}]
326
327*/
328
330#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, pre) \
331 ((((major)*UINT32_C(1)) << 24) | (((minor)*UINT32_C(1)) << 16) | (((patch)*UINT32_C(1)) << 8) | (((pre)*UINT32_C(1)) << 0))
332
334#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
335 ((((v)*UINT32_C(1)) >> 24u) & 0xFFu)
336
338#define ARDUINO_LMIC_VERSION_GET_MINOR(v) \
339 ((((v)*UINT32_C(1)) >> 16u) & 0xFFu)
340
342#define ARDUINO_LMIC_VERSION_GET_PATCH(v) \
343 ((((v)*UINT32_C(1)) >> 8u) & 0xFFu)
344
346#define ARDUINO_LMIC_VERSION_GET_PRE(v) \
347 ((v) & 0xFFu)
348
352#if (defined(__GNUC__) && __GNUC__ >= 6) || defined(__clang__)
353# define LMIC_DEPRECATED(msg) __attribute__((deprecated(msg)))
354#else
355# define LMIC_DEPRECATED(msg) /* nothing */
356#endif
357
363enum { ARDUINO_LMIC_VERSION_GET_LOCAL_is_deprecated LMIC_DEPRECATED("use ARDUINO_LMIC_VERSION_GET_PRE()") = 0 };
364
366#define ARDUINO_LMIC_VERSION_GET_LOCAL(v) \
367 (ARDUINO_LMIC_VERSION_GET_PRE(v) + ARDUINO_LMIC_VERSION_GET_LOCAL_is_deprecated)
368
370#define ARDUINO_LMIC_VERSION_TO_ORDINAL(v) \
371 (((v) & 0xFFFFFF00u) | (((v) - 1) & 0xFFu))
372
375#define ARDUINO_LMIC_VERSION_COMPARE_LT(a, b) \
376 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) < ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
377
380#define ARDUINO_LMIC_VERSION_COMPARE_LE(a, b) \
381 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) <= ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
382
385#define ARDUINO_LMIC_VERSION_COMPARE_GT(a, b) \
386 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) > ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
387
390#define ARDUINO_LMIC_VERSION_COMPARE_GE(a, b) \
391 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) >= ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
392
393#endif /* _lmic_env_h_ */