1、stm32f10x_conf.h 中关于断言的代码
#ifdef USE_FULL_ASSERT
/**
* @brief assert_param 宏用于函数的输入参数检查
* @param expr:若expr 值为假,则调用assert_failed 函数
* 报告文件名及错误行号
* 若expr 值为真,则不执行操作
**/
#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 /* USE_FULL_ASSERT */
2、分析说明
在ST 标准库的函数中,一般会包含输入参数检查,即上述代码中的“assert_param”宏,当参数不符合要求时,会调用“assert_failed”函数,这个函数默认是空的。
实际开发中使用断言时,先通过定义USE_FULL_ASSERT 宏来使能断言,然后定义“assert_failed”函数,通常我们会让它调用printf 函数输出错误说明。使能断言后,程序运行时会检查函数的输入参数,当软件经过测试,可发布时,会取消USE_FULL_ASSERT宏来去掉断言功能,使程序全速运行。
3、代码分析
这里的“assert_param”实际是一个宏,在库函数中它用于检查输入参数是否符合要求。这段代码的意思是,假如我们不定义“USE_FULL_ASSERT”宏,那么“assert_param”就是一个空的宏(#else 与#endif 之间的语句生效),没有任何操作。从而所有库函数中的assert_param 实际上都无意义,我们就当看不见好了。
假如我们定义“USE_FULL_ASSERT”宏,那么“assert_param”就是一个有操作的语句(#if 与#else 之间的语句生效),该宏对参数expr 使用C 语言中的问号表达式进行判断,若expr 值为真,则无操作(void 0),若表达式的值为假,则调用“assert_failed”函数,且该函数的输入参数为“__FILE__”及“__LINE__”,这两个参数分别代表 “assert_param”宏被调用时所在的“文件名”及“行号”。
但库文件只对“assert_failed”写了函数声明,没有写函数定义,实际用时需要用户来定义,我们一般会用printf 函数来输出这些信息。
void assert_failed(uint8_t* file, uint32_t line)
{
printf(“\r\n 输入参数错误,错误文件名=%s,行号=%s”,file,line);
}