OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13893|回复: 4

keil编译出错,编译结果为Error: L6218E: Undefined symbol assert_failed (referred from misc.o).

[复制链接]

7

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2017-5-6
在线时间
24 小时
发表于 2017-12-12 12:50: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  。
简直不敢相信啊!!!所以,实际中还是不要用的好,原因不言自明,库函数用到这个参数校验的太多了。我是把所有的库函数都加入到工程中了,习惯吧!所以,就会有这个结果了。

大家,有没有实际中用到这个的,有没有也遇到这种情况的,相互学习交流下!

实际打印的结果

实际打印的结果
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2018-8-5
在线时间
15 小时
发表于 2020-11-30 17:05:05 | 显示全部楼层
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2020-11-30 17:53:33 | 显示全部楼层
是用这个宏调用的 assert_param(0);
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2020-11-30 17:54:22 | 显示全部楼层
另外进这个函数打印是可以的, 但请先关了中断
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2020-11-30 17:58:26 | 显示全部楼层
这是帮你查错的工具, 在验证后就会把USE_FULL_ASSERT去掉的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 01:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表