初级会员

- 积分
- 120
- 金钱
- 120
- 注册时间
- 2017-5-6
- 在线时间
- 24 小时
|
本帖最后由 centos 于 2017-12-12 12:59 编辑
开发STM32中,我们都会用到STM32官方的固件库,我们仔细看每个函数,都会发现它写的函数中都会有一个参数校验的函数,例如最常用的引脚初始化函数void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)固件库函数开头为:
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
其中,assert_param()函数为参数校验的,进一步搜索发现,它定义在stm32f10x_conf.h文件中。仔细看看源码,发现它实际中一般是没有用的,以下是源码,大家自己看。(可以参考下战舰下的源码工程)
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */
/* 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)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 */
USE_FULL_ASSERT宏默认是关闭,也就是无论什么时候,它都是#define assert_param(expr) ((void)0)这样的结果。所以,有没有用大家应该清楚了。我想着把宏开启了,实际测试下,看看有什么用,也就是如果我输入的参数有误,它会怎么处理。实际上,就是看看
void assert_failed(uint8_t* file, uint32_t line)这个函数怎么处理的。可是,我打开宏编译后一直有链接错误,如下:..\Output\release.axf: Error: L6218E: Undefined symbol assert_failed (referred from misc.o).
这种情况,一般是函数,变量引用了,没有正确定义或者说定义了,没有声明吧!网上怎么搜索,都没有相关的解决方法,自己摸索着写了一个函数原型:void assert_failed(uint8_t* file, uint32_t 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) */
/* Infinite loop */
while (1)
{
printf("Wrong parameters value: file %s on line %d\r\n", file, line);
delay_ms(1000);
}
}
实际中是可以起作用的。下载到板子上,开启串口打印,这时如果在编写函数中,使用了错误参数,例如不在某一个约定的范围内,会一直打印第几行第几列错误。
这个只是个调试的手段,就是把传递到函数的参数进行校验。默认,应该都是关闭的。还有,如果大家要用会发现,加不加入参数校验,编译前后代码字节数差别很大的。所以还是建议不要加入这个参数校验。例如:我自己的工程原来没有参数校验,编译出来,代码体积为Program Size: Code=16852 RO-data=1180 RW-data=68 ZI-data=6892 ;加入后编译出来,代码体积为Program Size: Code=33632 RO-data=1180 RW-data=68 ZI-data=6892 。
简直不敢相信啊!!!所以,实际中还是不要用的好,原因不言自明,库函数用到这个参数校验的太多了。我是把所有的库函数都加入到工程中了,习惯吧!所以,就会有这个结果了。
大家,有没有实际中用到这个的,有没有也遇到这种情况的,相互学习交流下!
|
-
实际打印的结果
|