搜索
查看: 1225|回复: 3

[STM32F103] STM32F1 HAL / LL Driver HAL_Delay() 的Bug

[复制链接]

该用户从未签到

3

主题

7

帖子

0

蝴蝶豆

新手上路

最后登录
2020-2-11
发表于 2020-2-1 00:25:00 | 显示全部楼层 |阅读模式
刚开始学习STM32,在使用STM32CubeIDE,以STM32F103为基础开学。安装了STM32Cube_FW_F1_V1.8.0,这两天把STM32F1 HAL的基础部分看完了,对于HAL_Delay()这个功能有一些疑虑:
该函数是基于Systick计数器实现的,把Systick计数器组态为每1ms自动重载一次,同时启动中断程序,给32位无符号全局参数uwTick累加1,也就是说uwTick相当于每1ms会自动+1,在HAL_Delay()函数中等待从调用它开始到目前uwTick增加的数,来实现以ms位单位的延时,具体函数如下:
__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;
  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}


但是程序里没有对uwTick做上溢回零后的处理和保护,那么当在上溢发生前启动延时,而且上溢前延时还没有达到,而发生了上溢则uwTick又从零来时累计了,那么该延时就不会完成,就可能会触发看门狗而其他重启了。
举例来说:无符号32位数最大值位4,294,967,296(不到一点50天),当uwTick累计到接近最大值的时候,比如说差1ms时启动了延时5ms,那么按照上面的函数就永远都无法跳出while循环了。
而一般来说,在功能测试期间,很少会让系统连续跑超过50天进行测试,而即使有超过50天的连续测试,如果没有在上面的极端情况发生,也很少有机会发现这个bug,但是这种可能性还是存在的,如果使用的延时功能够多,那么在系统投入实际运行后,这种问题一定会发生。
建议在delay函数里做一点修正:只要判断uwTick是否有上溢,在做相应的保护就可以了。
由于我是做工业控制系统的,所以对于系统连续运行性能要求比较高,所以在此提出一点疑虑和建议。当然了对于民用或者一些对于连续运行要求不高的场合,这种问题就无所谓了。
回复

使用道具 举报

该用户从未签到

3

主题

7

帖子

0

蝴蝶豆

新手上路

最后登录
2020-2-11
 楼主| 发表于 2020-2-11 04:48:08 | 显示全部楼层
今天特意测试了一下HAL_Delay,当uwTick发生上溢后从0开始计数后,由于是使用的无符号数,所以小数字-大数字,会变成一个更大的数,所以结果肯定大于等待值,系统不至于重启,只是延时时间会变得不准确而已。
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

7

帖子

2

蝴蝶豆

初级会员

最后登录
2020-7-30
发表于 2020-3-3 12:58:56 | 显示全部楼层
其实应该理解为符号数,这样完全不用考虑溢出问题,1-0xffffffff=1-(-1)=2;
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

2

帖子

0

蝴蝶豆

新手上路

最后登录
2020-7-1
发表于 2020-3-20 21:45:09 | 显示全部楼层
复习一下计算机组成原理就明白了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-27 21:07 , Processed in 1.161283 second(s), 32 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

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