STM32 一种参数检查用法介绍
assert_param()
是一个在代码中很常见的写法,这个函数的功能一般是对函数参数的合法性进行检查,这里以一个例子进行分析:
assert_param(IS_GPIO_ALL_PERIPH(GPIOx))
函数的参数是IS_GPIO_ALL_PERIPH(GPIOx)
,原型为:
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) ||
((PERIPH) == GPIOB) ||
((PERIPH) == GPIOC) ||
((PERIPH) == GPIOD) ||
((PERIPH) == GPIOE) ||
((PERIPH) == GPIOF) ||
((PERIPH) == GPIOG) ||
((PERIPH) == GPIOH) ||
((PERIPH) == GPIOI) ||
((PERIPH) == GPIOJ) ||
((PERIPH) == GPIOK))
这个宏定义的作用就是检查参数PERIPH,判断参数PERIPH是否为GPIOX(A...G)基址中的一个,只要有一个为真则其值为真,否则为假。由于这个是宏定义,因此并不是在编译的时候进行判断上的简化,而是将多行代码用宏定义代替了。
下面再看看assert_param
:
assert_param
函数原型如下:
代码语言:javascript复制#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)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
这里有一个判断,如果是FULL ASSERT,则宏定义被展开为:((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
,否则则被展开为((void)0)
。
先看第二种:
如果被展开为((void)0)
,则相当于什么也没做,那么看第一种,如果expr
为真,则跟第二种的处理一样,什么也不做,如果expr
为假,则执行断言失败assert_failed((uint8_t *)__FILE__, __LINE__))
既然如果选择了FULL ASSERT,那么就有断言失败的可能,因此,这里把断言失败的函数声明写上,即可避免编译错误。
再看断言失败的处理: