在Betaflight源码.h文件中会有许多如下,使用STATIC_ASSERT定义调用的语句
STATIC_ASSERT(OSD_WARNING_COUNT <= 32, osdwarnings_overflow);
并发现STATIC_ASSERT的定义为_Static_assert
#define STATIC_ASSERT(condition, name) _Static_assert((condition), #name)
_Static_assert也是一个宏,叫作静态断言。其作用是,如果条件(condition)为0,则在编译窗口显示#name;如果条件(condition)为1,则什么不执行。常用于检测程序中的错误,如定义数组int a[10],确在程序中调用了第11个元素: a[10] = 11;
_Static_assert似乎是在交叉编译器(gcc-arm-none-eabi)中定义的,没有找到具体定义,但在linux下实测功能运行正常。
而keil下用来编译程序的却不是gcc-arm-none-eabi,导致移植到keil中该部分程序会报错。另一方面Stm32的库有类似断言的一个宏定义:assert_param
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif
具体原理,参考:详解stm32中的assert_param()函数_stm32 assert_param-CSDN博客
这里是当USE_FULL_ASSERT有定义时才会执行有效的断言函数,函数定义为 assert_failed((uint8_t *)__FILE__, __LINE__)),这是一个自定义的函数“__FILE__”是错误文件名,“__LINE__”是错误的行号,可以参考定义为(在my_assert.c中):
void assert_failed(u8* file, u32 line)
{
//User can add his own implementation to report the file name and line number,
// ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line)
//用户可以在这里添加错误信息:比如打印出出错的文件名和行号
char Tx_date[60] = {0};
system_clock_config(); //初始化涉及到的相关外设
at32_board_init();
ANO_init_usart(230400);
sprintf(Tx_date, "Wrong parameters value: file %s on line %d\r\n", file, line);
// Infinite loop
while (1)
{
ANO_tx_buffer((uint8*)Tx_date, sizeof(Tx_date));
delay_sec(1);
}
}
而在飞控中可以使用ANO所定义的串口进行输出信息。
这里使用自定义的断言函数来替换BF源码中STATIC_ASSERT有关的静态断言。