Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_Common/AP_Common.h
9526 views
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 hex_to_uint8(uint8_t a, uint8_t &res); // return the uint8 value of an ascii hex character
173
174
/*
175
strncpy without the warning for not leaving room for nul termination
176
*/
177
size_t strncpy_noterm(char *dest, const char *src, size_t n);
178
179
// return the numeric value of an ascii hex character
180
uint8_t char_to_hex(char a);
181
182
/*
183
Bit manipulation
184
*/
185
//#define BIT_SET(value, bitnumber) ((value) |= (((typeof(value))1U) << (bitnumber)))
186
template <typename T> void BIT_SET (T& value, uint8_t bitnumber) noexcept {
187
static_assert(std::is_integral<T>::value, "Integral required.");
188
((value) |= ((T)(1U) << (bitnumber)));
189
}
190
//#define BIT_CLEAR(value, bitnumber) ((value) &= ~(((typeof(value))1U) << (bitnumber)))
191
template <typename T> void BIT_CLEAR (T& value, uint8_t bitnumber) noexcept {
192
static_assert(std::is_integral<T>::value, "Integral required.");
193
((value) &= ~((T)(1U) << (bitnumber)));
194
}
195
196
/*
197
See the comments in libraries/AP_Common/c++.cpp
198
*/
199
#ifndef NEW_NOTHROW
200
#define NEW_NOTHROW new(std::nothrow)
201
#endif
202
203
void * WEAK mem_realloc(void *ptr, size_t old_size, size_t new_size);
204
205