2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
24 #define ARRAYEND(x) (&(x)[ARRAYLEN(x)])
25 #define ZERO_FARRAY(a) memset(a, 0, sizeof(a))
27 #define CONST_CAST(type, value) ((type)(value))
29 #define CONCAT_HELPER(x,y) x ## y
30 #define CONCAT(x,y) CONCAT_HELPER(x, y)
32 #define CONCAT3_HELPER(x, y, z) x ## y ## z
33 #define CONCAT3(x, y, z) CONCAT3_HELPER(x, y, z)
35 #define CONCAT4_HELPER(x, y, z, w) x ## y ## z ## w
36 #define CONCAT4(x, y, z, w) CONCAT4_HELPER(x, y, z, w)
38 #define STR_HELPER(x) #x
39 #define STR(x) STR_HELPER(x)
42 #define EXPAND(x) EXPAND_I(x)
44 // Expand all argumens and call macro with them. When expansion of some argument contains ',', it will be passed as multiple arguments
45 // #define TAKE3(_1,_2,_3) CONCAT3(_1,_2,_3)
47 // PP_CALL(TAKE3, MULTI2, C) expands to ABC
48 #define PP_CALL(macro, ...) macro(__VA_ARGS__)
51 #define UNUSED(x) (void)(x)
54 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
56 #define BIT(x) (1 << (x))
57 #define GET_BIT(value, bit) ((value >> bit) & 1)
59 #define STATIC_ASSERT(condition, name) \
60 typedef char assert_failed_ ## name [(condition) ? 1 : -1 ] __attribute__((unused))
63 http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html
65 #define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
66 #define BX_(x) ((x) - (((x)>>1)&0x77777777) - (((x)>>2)&0x33333333) - (((x)>>3)&0x11111111))
70 * https://groups.google.com/forum/?hl=en#!msg/comp.lang.c/attFnqwhvGk/sGBKXvIkY3AJ
71 * Return (v ? floor(log2(v)) : 0) when 0 <= v < 1<<[8, 16, 32, 64].
72 * Inefficient algorithm, intended for compile-time constants.
74 #define LOG2_8BIT(v) (8 - 90/(((v)/4+14)|1) - 2/((v)/2+1))
75 #define LOG2_16BIT(v) (8*((v)>255) + LOG2_8BIT((v) >>8*((v)>255)))
76 #define LOG2_32BIT(v) (16*((v)>65535L) + LOG2_16BIT((v)*1L >>16*((v)>65535L)))
77 #define LOG2_64BIT(v) \
78 (32*((v)/2L>>31 > 0) \
79 + LOG2_32BIT((v)*1L >>16*((v)/2L>>31 > 0) \
80 >>16*((v)/2L>>31 > 0)))
82 // non ISO variant from linux kernel; checks ptr type, but triggers 'ISO C forbids braced-groups within expressions [-Wpedantic]'
83 // __extension__ is here to disable this warning
84 #define container_of(ptr, type, member) ( __extension__ ({ \
85 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
86 (type *)( (char *)__mptr - offsetof(type,member) );}))
88 static inline int16_t cmp16(uint16_t a
, uint16_t b
) { return a
-b
; }
89 static inline int32_t cmp32(uint32_t a
, uint32_t b
) { return a
-b
; }
91 // using memcpy_fn will force memcpy function call, instead of inlining it. In most cases function call takes fewer instructions
92 // than inlined version (inlining is cheaper for very small moves < 8 bytes / 2 store instructions)
93 #if defined(UNIT_TEST) || defined(SITL_BUILD)
95 #define memcpy_fn(destination, source, num) memcpy(destination, source, num)
97 void *memcpy_fn(void *destination
, const void *source
, size_t num
) asm("memcpy");
101 #define FALLTHROUGH __attribute__ ((fallthrough))
103 #define FALLTHROUGH do {} while(0)
106 #define UNREACHABLE() __builtin_unreachable()
108 #define ALIGNED(x) __attribute__ ((aligned(x)))
110 #define PACKED __attribute__((packed))