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

STM32F1 HAL / LL Driver HAL_Delay() 的Bug

[复制链接]
wwmbt 提问时间:2020-2-1 00:25 /
刚开始学习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 发布时间:2020-2-1 00:25

举报

3个回答
wwmbt 回答时间:2020-2-11 04:48:08
今天特意测试了一下HAL_Delay,当uwTick发生上溢后从0开始计数后,由于是使用的无符号数,所以小数字-大数字,会变成一个更大的数,所以结果肯定大于等待值,系统不至于重启,只是延时时间会变得不准确而已。
sxying 回答时间:2020-3-3 12:58:56
其实应该理解为符号数,这样完全不用考虑溢出问题,1-0xffffffff=1-(-1)=2;
zlfxia 回答时间:2020-3-20 21:45:09
复习一下计算机组成原理就明白了
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版