在线时间3 小时
UID3612717
ST金币0
蝴蝶豆0
注册时间2020-1-29
新手上路
- 最后登录
- 2020-2-11
|
a0a.1 32b0c
刚开始学习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是否有上溢,在做相应的保护就可以了。
由于我是做工业控制系统的,所以对于系统连续运行性能要求比较高,所以在此提出一点疑虑和建议。当然了对于民用或者一些对于连续运行要求不高的场合,这种问题就无所谓了。
|
|