2013-08-29 02:34:34 -03:00
|
|
|
/*
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
2010-09-11 03:13:28 -03:00
|
|
|
|
2013-08-29 02:34:34 -03:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2010-09-11 03:13:28 -03:00
|
|
|
///
|
2012-08-17 03:18:11 -03:00
|
|
|
/// @file AP_Common.h
|
2010-09-11 03:13:28 -03:00
|
|
|
/// @brief Common definitions and utility routines for the ArduPilot
|
|
|
|
/// libraries.
|
|
|
|
///
|
|
|
|
|
2015-12-07 16:24:02 -04:00
|
|
|
#pragma once
|
2011-03-21 04:25:48 -03:00
|
|
|
|
2010-09-24 02:50:02 -03:00
|
|
|
#include <stdint.h>
|
2013-01-01 23:43:50 -04:00
|
|
|
#include <stdlib.h>
|
2020-08-04 17:45:52 -03:00
|
|
|
#include <type_traits>
|
2011-01-23 22:44:31 -04:00
|
|
|
|
2013-04-19 04:47:27 -03:00
|
|
|
// used to pack structures
|
|
|
|
#define PACKED __attribute__((__packed__))
|
|
|
|
|
2018-08-08 10:35:36 -03:00
|
|
|
// used to weaken symbols
|
|
|
|
#define WEAK __attribute__((__weak__))
|
|
|
|
|
2015-02-17 20:12:43 -04:00
|
|
|
// used to mark a function that may be unused in some builds
|
|
|
|
#define UNUSED_FUNCTION __attribute__((unused))
|
|
|
|
|
2022-02-26 09:51:26 -04:00
|
|
|
// used to mark an attribute that may be unused in some builds
|
|
|
|
#ifdef __clang__
|
|
|
|
#define UNUSED_PRIVATE_MEMBER __attribute__((unused))
|
|
|
|
#else
|
|
|
|
#define UNUSED_PRIVATE_MEMBER
|
|
|
|
#endif
|
|
|
|
|
2013-10-02 03:09:13 -03:00
|
|
|
// this can be used to optimize individual functions
|
|
|
|
#define OPTIMIZE(level) __attribute__((optimize(level)))
|
|
|
|
|
2015-05-20 20:35:26 -03:00
|
|
|
// sometimes we need to prevent inlining to prevent large stack usage
|
2022-11-10 12:50:28 -04:00
|
|
|
#ifndef NOINLINE
|
2015-05-20 20:35:26 -03:00
|
|
|
#define NOINLINE __attribute__((noinline))
|
2022-11-10 12:50:28 -04:00
|
|
|
#endif
|
2015-05-20 20:35:26 -03:00
|
|
|
|
2020-01-11 02:30:27 -04:00
|
|
|
// used to ignore results for functions marked as warn unused
|
|
|
|
#define IGNORE_RETURN(x) do {if (x) {}} while(0)
|
|
|
|
|
2015-11-10 13:05:19 -04:00
|
|
|
#define FMT_PRINTF(a,b) __attribute__((format(printf, a, b)))
|
2015-11-05 23:40:18 -04:00
|
|
|
#define FMT_SCANF(a,b) __attribute__((format(scanf, a, b)))
|
2015-10-22 12:06:18 -03:00
|
|
|
|
2021-06-06 05:26:25 -03:00
|
|
|
// used to forbid copy of objects
|
|
|
|
#define CLASS_NO_COPY(c) c(const c &other) = delete; c &operator=(const c&) = delete
|
|
|
|
|
2017-08-22 14:25:54 -03:00
|
|
|
#ifdef __has_cpp_attribute
|
|
|
|
# if __has_cpp_attribute(fallthrough)
|
|
|
|
# define FALLTHROUGH [[fallthrough]]
|
|
|
|
# elif __has_cpp_attribute(gnu::fallthrough)
|
|
|
|
# define FALLTHROUGH [[gnu::fallthrough]]
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
#ifndef FALLTHROUGH
|
|
|
|
# define FALLTHROUGH
|
|
|
|
#endif
|
|
|
|
|
2019-02-11 02:04:24 -04:00
|
|
|
#ifdef __GNUC__
|
|
|
|
#define WARN_IF_UNUSED __attribute__ ((warn_unused_result))
|
|
|
|
#else
|
|
|
|
#define WARN_IF_UNUSED
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define NORETURN __attribute__ ((noreturn))
|
|
|
|
|
2012-12-19 02:02:13 -04:00
|
|
|
#define ToRad(x) radians(x) // *pi/180
|
|
|
|
#define ToDeg(x) degrees(x) // *180/pi
|
2013-04-23 10:05:02 -03:00
|
|
|
|
2016-06-07 14:17:07 -03:00
|
|
|
/* Declare and implement const and non-const versions of the array subscript
|
|
|
|
* operator. The object is treated as an array of type_ values. */
|
2016-06-23 19:56:17 -03:00
|
|
|
#define DEFINE_BYTE_ARRAY_METHODS \
|
|
|
|
inline uint8_t &operator[](size_t i) { return reinterpret_cast<uint8_t *>(this)[i]; } \
|
|
|
|
inline uint8_t operator[](size_t i) const { return reinterpret_cast<const uint8_t *>(this)[i]; }
|
2016-06-07 14:17:07 -03:00
|
|
|
|
2013-04-23 10:05:02 -03:00
|
|
|
/*
|
|
|
|
check if bit bitnumber is set in value, returned as a
|
|
|
|
bool. Bitnumber starts at 0 for the first bit
|
|
|
|
*/
|
|
|
|
#define BIT_IS_SET(value, bitnumber) (((value) & (1U<<(bitnumber))) != 0)
|
2022-07-20 22:13:50 -03:00
|
|
|
#define BIT_IS_SET_64(value, bitnumber) (((value) & (uint64_t(1U)<<(bitnumber))) != 0)
|
2013-04-23 10:05:02 -03:00
|
|
|
|
2014-06-11 04:16:09 -03:00
|
|
|
// get high or low bytes from 2 byte integer
|
|
|
|
#define LOWBYTE(i) ((uint8_t)(i))
|
|
|
|
#define HIGHBYTE(i) ((uint8_t)(((uint16_t)(i))>>8))
|
|
|
|
|
2018-08-02 20:23:24 -03:00
|
|
|
#define ARRAY_SIZE(_arr) (sizeof(_arr) / sizeof(_arr[0]))
|
2015-07-02 12:11:32 -03:00
|
|
|
|
2020-10-05 22:13:09 -03:00
|
|
|
#define UINT16_VALUE(hbyte, lbyte) (static_cast<uint16_t>(((hbyte)<<8)|(lbyte)))
|
2021-12-10 01:55:14 -04:00
|
|
|
#define UINT32_VALUE(b3, b2, b1, b0) (static_cast<uint32_t>(((b3)<<24)|((b2)<<16)|((b1)<<8)|(b0)))
|
2019-03-27 08:06:55 -03:00
|
|
|
|
2016-06-21 16:34:45 -03:00
|
|
|
/*
|
|
|
|
* See UNUSED_RESULT. The difference is that it receives @uniq_ as the name to
|
|
|
|
* be used for its internal variable.
|
|
|
|
*
|
|
|
|
* @uniq_: a unique name to use for variable name
|
|
|
|
* @expr_: the expression to be evaluated
|
|
|
|
*/
|
|
|
|
#define _UNUSED_RESULT(uniq_, expr_) \
|
|
|
|
do { \
|
|
|
|
decltype(expr_) uniq_ __attribute__((unused)); \
|
|
|
|
uniq_ = expr_; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allow to call a function annotated with warn_unused_result attribute
|
|
|
|
* without getting a warning, because sometimes this is what we want to do.
|
|
|
|
*
|
|
|
|
* @expr_: the expression to be evaluated
|
|
|
|
*/
|
|
|
|
#define UNUSED_RESULT(expr_) _UNUSED_RESULT(__unique_name_##__COUNTER__, expr_)
|
|
|
|
|
2010-12-28 17:30:29 -04:00
|
|
|
// @}
|
|
|
|
|
2022-02-09 18:07:19 -04:00
|
|
|
// STR_VALUE returns the string equivalent for the passed cpp macro, so e.g.
|
|
|
|
// printf("%s", STR_VALUE(EINVAL)); will print "EINVAL"
|
|
|
|
#define STR_VALUE(x) #x
|
2010-12-28 17:30:29 -04:00
|
|
|
|
2018-12-31 17:52:36 -04:00
|
|
|
// assert_storage_size template: assert that the memory used to store an
|
|
|
|
// item is of a specific size.
|
|
|
|
// example invocation:
|
|
|
|
// assert_storage_size<class Location, 16> _assert_storage_size_Location;
|
|
|
|
// templates are used for this because the compiler's output will
|
|
|
|
// usually contain details of the template instantiation so you can
|
|
|
|
// see how the actual size differs from the expected size.
|
2019-04-03 20:15:26 -03:00
|
|
|
template<typename s, size_t s_size, size_t t> struct _assert_storage_size {
|
2018-12-31 17:52:36 -04:00
|
|
|
static_assert(s_size == t, "wrong size");
|
|
|
|
};
|
2019-04-03 20:15:26 -03:00
|
|
|
template<typename s, size_t t> struct assert_storage_size {
|
2018-12-31 17:52:36 -04:00
|
|
|
_assert_storage_size<s, sizeof(s), t> _member;
|
|
|
|
};
|
|
|
|
|
2023-12-13 19:20:16 -04:00
|
|
|
#define ASSERT_STORAGE_SIZE_JOIN( name, line ) ASSERT_STORAGE_SIZE_DO_JOIN( name, line )
|
|
|
|
#define ASSERT_STORAGE_SIZE_DO_JOIN( name, line ) name ## line
|
|
|
|
#define ASSERT_STORAGE_SIZE(structure, size) \
|
|
|
|
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)
|
|
|
|
|
2010-09-11 03:13:28 -03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// @name Conversions
|
|
|
|
///
|
|
|
|
/// Conversion macros and factors.
|
|
|
|
///
|
|
|
|
//@{
|
|
|
|
|
2015-11-08 17:47:45 -04:00
|
|
|
/*
|
|
|
|
Return true if value is between lower and upper bound inclusive.
|
|
|
|
False otherwise.
|
|
|
|
*/
|
|
|
|
bool is_bounded_int32(int32_t value, int32_t lower_bound, int32_t upper_bound);
|
2019-07-12 05:52:37 -03:00
|
|
|
|
|
|
|
bool hex_to_uint8(uint8_t a, uint8_t &res); // return the uint8 value of an ascii hex character
|
2020-07-07 00:14:13 -03:00
|
|
|
|
|
|
|
/*
|
|
|
|
strncpy without the warning for not leaving room for nul termination
|
|
|
|
*/
|
2023-01-06 08:03:34 -04:00
|
|
|
size_t strncpy_noterm(char *dest, const char *src, size_t n);
|
2020-08-04 17:45:52 -03:00
|
|
|
|
2021-11-02 21:09:08 -03:00
|
|
|
// return the numeric value of an ascii hex character
|
|
|
|
int16_t char_to_hex(char a);
|
|
|
|
|
2020-08-04 17:45:52 -03:00
|
|
|
/*
|
|
|
|
Bit manipulation
|
|
|
|
*/
|
|
|
|
//#define BIT_SET(value, bitnumber) ((value) |= (((typeof(value))1U) << (bitnumber)))
|
|
|
|
template <typename T> void BIT_SET (T& value, uint8_t bitnumber) noexcept {
|
|
|
|
static_assert(std::is_integral<T>::value, "Integral required.");
|
|
|
|
((value) |= ((T)(1U) << (bitnumber)));
|
|
|
|
}
|
|
|
|
//#define BIT_CLEAR(value, bitnumber) ((value) &= ~(((typeof(value))1U) << (bitnumber)))
|
|
|
|
template <typename T> void BIT_CLEAR (T& value, uint8_t bitnumber) noexcept {
|
|
|
|
static_assert(std::is_integral<T>::value, "Integral required.");
|
|
|
|
((value) &= ~((T)(1U) << (bitnumber)));
|
|
|
|
}
|
2023-05-21 00:54:58 -03:00
|
|
|
|