Line data Source code
1 : /*
2 : This program is free software: you can redistribute it and/or modify
3 : it under the terms of the GNU General Public License as published by
4 : the Free Software Foundation, either version 3 of the License, or
5 : (at your option) any later version.
6 :
7 : This program is distributed in the hope that it will be useful,
8 : but WITHOUT ANY WARRANTY; without even the implied warranty of
9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 : GNU General Public License for more details.
11 :
12 : You should have received a copy of the GNU General Public License
13 : along with this program. If not, see <http://www.gnu.org/licenses/>.
14 : */
15 : ///
16 : /// @file AP_Common.h
17 : /// @brief Common definitions and utility routines for the ArduPilot
18 : /// libraries.
19 : ///
20 :
21 : #pragma once
22 :
23 : #include <stdint.h>
24 : #include <stdlib.h>
25 : #include <type_traits>
26 : #include <new>
27 :
28 : // used to pack structures
29 : #define PACKED __attribute__((__packed__))
30 :
31 : #if !defined(CYGWIN_BUILD)
32 : // used to weaken symbols
33 : #define WEAK __attribute__((__weak__))
34 : #else
35 : // cygwin cannot properly support weak symbols allegedly due to Windows
36 : // executable format limitations
37 : // (see https://www.cygwin.com/faq.html#faq.programming.linker ). fortunately
38 : // we only use weak symbols for tests and some HAL stuff which SITL and
39 : // therefore cygwin does not need to override. in the event that overriding is
40 : // attempted the link will fail with a symbol redefinition error hopefully
41 : // suggesting that an alternate approach is needed.
42 : #define WEAK
43 : #endif
44 :
45 : // used to mark a function that may be unused in some builds
46 : #define UNUSED_FUNCTION __attribute__((unused))
47 :
48 : // used to mark an attribute that may be unused in some builds
49 : #ifdef __clang__
50 : #define UNUSED_PRIVATE_MEMBER __attribute__((unused))
51 : #else
52 : #define UNUSED_PRIVATE_MEMBER
53 : #endif
54 :
55 : // this can be used to optimize individual functions
56 : #define OPTIMIZE(level) __attribute__((optimize(level)))
57 :
58 : // sometimes we need to prevent inlining to prevent large stack usage
59 : #ifndef NOINLINE
60 : #define NOINLINE __attribute__((noinline))
61 : #endif
62 :
63 : // used to ignore results for functions marked as warn unused
64 : #define IGNORE_RETURN(x) do {if (x) {}} while(0)
65 :
66 : #define FMT_PRINTF(a,b) __attribute__((format(printf, a, b)))
67 : #define FMT_SCANF(a,b) __attribute__((format(scanf, a, b)))
68 :
69 : // used to forbid copy of objects
70 : #define CLASS_NO_COPY(c) c(const c &other) = delete; c &operator=(const c&) = delete
71 :
72 : #ifdef __has_cpp_attribute
73 : # if __has_cpp_attribute(fallthrough)
74 : # define FALLTHROUGH [[fallthrough]]
75 : # elif __has_cpp_attribute(gnu::fallthrough)
76 : # define FALLTHROUGH [[gnu::fallthrough]]
77 : # endif
78 : #endif
79 : #ifndef FALLTHROUGH
80 : # define FALLTHROUGH
81 : #endif
82 :
83 : #ifdef __GNUC__
84 : #define WARN_IF_UNUSED __attribute__ ((warn_unused_result))
85 : #else
86 : #define WARN_IF_UNUSED
87 : #endif
88 :
89 : #define NORETURN __attribute__ ((noreturn))
90 :
91 : /* Declare and implement const and non-const versions of the array subscript
92 : * operator. The object is treated as an array of type_ values. */
93 : #define DEFINE_BYTE_ARRAY_METHODS \
94 : inline uint8_t &operator[](size_t i) { return reinterpret_cast<uint8_t *>(this)[i]; } \
95 : inline uint8_t operator[](size_t i) const { return reinterpret_cast<const uint8_t *>(this)[i]; }
96 :
97 : /*
98 : check if bit bitnumber is set in value, returned as a
99 : bool. Bitnumber starts at 0 for the first bit
100 : */
101 : #define BIT_IS_SET(value, bitnumber) (((value) & (1U<<(bitnumber))) != 0)
102 : #define BIT_IS_SET_64(value, bitnumber) (((value) & (uint64_t(1U)<<(bitnumber))) != 0)
103 :
104 : // get high or low bytes from 2 byte integer
105 : #define LOWBYTE(i) ((uint8_t)(i))
106 : #define HIGHBYTE(i) ((uint8_t)(((uint16_t)(i))>>8))
107 :
108 : #define ARRAY_SIZE(_arr) (sizeof(_arr) / sizeof(_arr[0]))
109 :
110 : #define UINT16_VALUE(hbyte, lbyte) (static_cast<uint16_t>(((hbyte)<<8)|(lbyte)))
111 : #define UINT32_VALUE(b3, b2, b1, b0) (static_cast<uint32_t>(((b3)<<24)|((b2)<<16)|((b1)<<8)|(b0)))
112 :
113 : /*
114 : * See UNUSED_RESULT. The difference is that it receives @uniq_ as the name to
115 : * be used for its internal variable.
116 : *
117 : * @uniq_: a unique name to use for variable name
118 : * @expr_: the expression to be evaluated
119 : */
120 : #define _UNUSED_RESULT(uniq_, expr_) \
121 : do { \
122 : decltype(expr_) uniq_ __attribute__((unused)); \
123 : uniq_ = expr_; \
124 : } while (0)
125 :
126 : /*
127 : * Allow to call a function annotated with warn_unused_result attribute
128 : * without getting a warning, because sometimes this is what we want to do.
129 : *
130 : * @expr_: the expression to be evaluated
131 : */
132 : #define UNUSED_RESULT(expr_) _UNUSED_RESULT(__unique_name_##__COUNTER__, expr_)
133 :
134 : // @}
135 :
136 : // STR_VALUE returns the string equivalent for the passed cpp macro, so e.g.
137 : // printf("%s", STR_VALUE(EINVAL)); will print "EINVAL"
138 : #define STR_VALUE(x) #x
139 :
140 : // assert_storage_size template: assert that the memory used to store an
141 : // item is of a specific size.
142 : // example invocation:
143 : // assert_storage_size<class Location, 16> _assert_storage_size_Location;
144 : // templates are used for this because the compiler's output will
145 : // usually contain details of the template instantiation so you can
146 : // see how the actual size differs from the expected size.
147 : template<typename s, size_t s_size, size_t t> struct _assert_storage_size {
148 : static_assert(s_size == t, "wrong size");
149 : };
150 : template<typename s, size_t t> struct assert_storage_size {
151 : _assert_storage_size<s, sizeof(s), t> _member;
152 : };
153 :
154 : #define ASSERT_STORAGE_SIZE_JOIN( name, line ) ASSERT_STORAGE_SIZE_DO_JOIN( name, line )
155 : #define ASSERT_STORAGE_SIZE_DO_JOIN( name, line ) name ## line
156 : #define ASSERT_STORAGE_SIZE(structure, size) \
157 : do { assert_storage_size<structure, size> ASSERT_STORAGE_SIZE_JOIN(assert_storage_sizex, __LINE__); (void)ASSERT_STORAGE_SIZE_JOIN(assert_storage_sizex, __LINE__); } while(false)
158 :
159 : ////////////////////////////////////////////////////////////////////////////////
160 : /// @name Conversions
161 : ///
162 : /// Conversion macros and factors.
163 : ///
164 : //@{
165 :
166 : /*
167 : Return true if value is between lower and upper bound inclusive.
168 : False otherwise.
169 : */
170 : bool is_bounded_int32(int32_t value, int32_t lower_bound, int32_t upper_bound);
171 :
172 : bool WARN_IF_UNUSED hex_char_to_nibble(uint8_t a, uint8_t &res); // return the uint8 value of an ascii hex character
173 :
174 : /*
175 : decode two hex characters into a byte.
176 : e.g. hex_twochars_to_uint8("3F", res) -> res = 0x3F
177 : */
178 : bool WARN_IF_UNUSED hex_twochars_to_uint8(const char s[2], uint8_t &res);
179 :
180 : /*
181 : decode num_pairs pairs of hex characters into bytes at out[]
182 : */
183 : bool WARN_IF_UNUSED hex_charpairs_to_uint8s(const char *s, uint8_t num_pairs, uint8_t *out);
184 :
185 : /*
186 : decode len hex characters into a uint32_t, treating each character
187 : as a nibble (most-significant first).
188 : e.g. hex_chars_to_uint32("1A2B", 4, out) -> out = 0x1A2B
189 : */
190 : bool WARN_IF_UNUSED hex_chars_to_uint32(const char *s, uint8_t len, uint32_t &out);
191 :
192 : /*
193 : strncpy without the warning for not leaving room for nul termination
194 : */
195 : size_t strncpy_noterm(char *dest, const char *src, size_t n);
196 :
197 :
198 : /*
199 : Bit manipulation
200 : */
201 : //#define BIT_SET(value, bitnumber) ((value) |= (((typeof(value))1U) << (bitnumber)))
202 19413 : template <typename T> void BIT_SET (T& value, uint8_t bitnumber) noexcept {
203 : static_assert(std::is_integral<T>::value, "Integral required.");
204 19413 : ((value) |= ((T)(1U) << (bitnumber)));
205 19413 : }
206 : //#define BIT_CLEAR(value, bitnumber) ((value) &= ~(((typeof(value))1U) << (bitnumber)))
207 77520 : template <typename T> void BIT_CLEAR (T& value, uint8_t bitnumber) noexcept {
208 : static_assert(std::is_integral<T>::value, "Integral required.");
209 77520 : ((value) &= ~((T)(1U) << (bitnumber)));
210 77520 : }
211 :
212 : /*
213 : See the comments in libraries/AP_Common/c++.cpp
214 : */
215 : #ifndef NEW_NOTHROW
216 : #define NEW_NOTHROW new(std::nothrow)
217 : #endif
218 :
219 : void * WEAK mem_realloc(void *ptr, size_t old_size, size_t new_size);
|