assert_param是一个宏定义,在程序开发中,它的作用就是检测传递给函数的参数是否是有效的参数。默认是不开启的,可以无视它的存在,但在调试程序时,可以打开这个检测机制,调试完再关闭。
从库函数源码可以看出,assert_param()的函数功能默认是不开启的,取消 #define USE_FULL_ASSERT 1U 的注释,可以开启该功能。
/* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ // #define USE_FULL_ASSERT 1U /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
该宏定义基于条件运算符,功能为:如果expr为真,则执行(void)0U,如果expr为假,则执行asser_failed()。
其中“ expr ”为判断参数是否合法的表达式,也可以用户自己定义,以下示例为判断串口句柄是否合法。
其中__FILE__ , __LINE__为编译器内置宏。
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
/******************** UART Instances : Half-Duplex mode **********************/ #define IS_UART_HALFDUPLEX_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ ((INSTANCE) == USART2) || \ ((INSTANCE) == USART3) || \ ((INSTANCE) == UART4) || \ ((INSTANCE) == UART5) || \ ((INSTANCE) == USART6)) /* Legacy defines */ #define IS_UART_INSTANCE IS_UART_HALFDUPLEX_INSTANCE
用户可自己定义断言失败函数asser_failed()的功能,如下所示。
#ifdef USE_FULL_ASSERT /** * 函数功能: 断言失败服务函数 * 输入参数: file : 源代码文件名称。关键字__FILE__表示源代码文件名。 * line :代码行号。关键字 __LINE__ 表示源代码行号 * 返 回 值: 无 * 说 明: 无 */ void assert_failed(uint8_t* file, uint32_t line) { /* * 用户可以添加自己的代码报告源代码文件名和代码行号,比如将错误文件和行号打印到串口 * printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* 这是一个死循环,断言失败时程序会在此处死机,以便于用户查错 */ while (1) { } } #endif
assert()中的(void(0))浅析
编译器内置宏