在使用STM32标准库进行开发的时候,经常会看到一个这样一个宏assert_param(),那么这个宏到底什么作用呢?
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
首先来看看官方对这一个宏的解释:
/**
* @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
*/
/**
* @brief 这个宏是用来进行函数参数的检验
* @param expr: 如果expr的值是false,它就会调用断言错误函数,
* 报告引发这个错误的文件名字和源代码行号
* 如果expr的值是true,它返回一个空的值
* @retval None (没有返回值)
*/
/******一、如果定义USE_FULL_ASSERT这个宏******/
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
/******二、如果没有定义USE_FULL_ASSERT这个宏******/
#else
#define assert_param(expr) ((void)0)
#endif
从以上解释我们就可以看出来,这个宏的作用就是为了检测函数的输入参数是否正确,乍一看,可能觉得是多此一举,认为这样的东西是纯粹是冗余的设计,但是如果是进行一个大型的工程设计,而我们在填写某一个函数的输入参数时出现错误,那这种错误的排查可是非常痛苦的,因为你有可能面临的是成千上万行代码,你去哪里找到这一个出错的参数呢?
所以,这种机制就能够有效地提高我们在调试阶段的效率,但是任何事物都有两面性,这个也不例外,你想想,在每一次调用这个函数的时候都进行了一次参数检验,这样会消耗过多的CPU资源,导致性能下降,所以,一般的话,我们只在调试阶段使用,而当准备发布最终版本的时候,我们需要将这个检测给取消,避免多次进行参数检测带来的资源消耗。
具体做法:在MDK环境下,我们可以使用全局定义的宏来实现:
- 首先点击魔术棒按钮,打开“Options for Target ”菜单,然后点击C/C++,
- 在下面的Define输入框里面输入我们想要的定义的全局宏,比如想要开启这个宏定义,就将***USE_FULL_ASSERT***输入到这个框框内,这样就会开启全局的一个宏定义。