你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 523|回复: 3

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

[复制链接]

3

主题

4

回帖

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

主题

4

回帖

0

蝴蝶豆

新手上路

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

使用道具 举报

2

主题

5

回帖

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 | 显示全部楼层
复习一下计算机组成原理就明白了
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版