与龙共舞 发表于 2018-4-20 08:55:53

质疑HAL库的延时函数HAL_Delay

是这样的,M3内核的滴答定时器一般用来做系统的时基,最频繁的变现就是延时函数了HAL_Delay。看一下延时函数的实现:
__weak void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}




是一个空空死循环,只要HAL_GetTick() - tickstart 值没有大于你设置的Delay数值。
在看一下
__weak void HAL_IncTick(void)
{
uwTick++;
}

__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}


其实这个HAL_GetTick()是一个全局变量。
static __IO uint32_t uwTick;
【预计上电以后默认是初始化为0的】

那么我的问题是:
比如我调用HAL_Delay(100),
此时uwTick是120,那么uwTick会随着时间脉冲++,
等uwTick到220的时候我的延时就从死循环出来了。
而如果【u32比较大 我就暂时当做u8吧 那就是255了】
我调用HAL_Delay(100),
此时uwTick是220,那么uwTick会随着时间脉冲++,理论到320的时候解除死循环,
而在255的时候,我擦,u8到了尽头了,会变到0!怎么办?


我想了一下 如果这样的话在255->0的时候回出现0-220的计算这个时候系统怎么处理呢?会直接解除死循环吗?
《我说的这种概率情况》
同时想起来刚刚做的笔试题目,是不是也是这个问题呢?

XinLiYF 发表于 2018-4-20 20:13:33

无符号的回环问题:(uint8_t)(0x00) - (uint8_t)(0xFF) = (uint8_t)(0x01)

这个是一个很好的例子:模仿kfifo实现的环形缓冲区

黑皮男 发表于 2018-4-20 18:14:49

与龙共舞 发表于 2018-4-20 16:29
所以你的这思路就是把U32提升到U64 再次降低出现溢出的可能吗?

不是,是无符号数和有符号数的问题。http://www.cnblogs.com/hfyinsdu/p/4600052.html

toofree 发表于 2018-4-20 09:13:49

本帖最后由 toofree 于 2018-4-20 09:15 编辑

HAL_Delay()函数的参数类型是uint32_t,即无符号32位int型。
如果超过32位的最大数(4亿多4294967296)的话,的确会有问题。那么延时会多长了呢,以标准的HAL_Delay()单位1ms计算,4294967296ms,4294967秒,1193小时。只能是人为判断,参数不要超过32位uint32_t。

freeelectron 发表于 2018-4-20 09:09:17

1、楼主说的这种情况的确有的,但是你要考虑实际,谁会延迟u32 那么大的时间啊
2、一般这种有死循环多的,还是尽量开看门狗

wenyangzeng 发表于 2018-4-20 09:46:13

uwTick是32位变量。不会出现楼主说的情况。

wudianjun2001 发表于 2018-4-20 09:50:25

32位的一般不会出现长时间的延时的

与龙共舞 发表于 2018-4-20 10:15:33

toofree 发表于 2018-4-20 09:13
HAL_Delay()函数的参数类型是uint32_t,即无符号32位int型。
如果超过32位的最大数(4亿多4294967296)的话 ...

哦 我传参是100 肯定OK
我说的是(猜测) 比如此时ucTick数值就是4294967290 那会发生什么事呢?它++100会回到0

jjbboox 发表于 2018-4-20 10:20:11

有什么好担心的,u32你知道需要等多少年吗?
time_t都没用完32位。

dsjsjf 发表于 2018-4-20 10:22:42

按照楼主所说,此时uwTick是220,那么uwTick会随着时间脉冲++,理论到320的时候解除死循环,
而在255的时候,我擦,u8到了尽头了,会变到0!实际上会加到64。再看死循环while((HAL_GetTick() - tickstart) < Delay)里,此时HAL_GetTick()为64,tickstart为220,因为都是无符号数,因而64-220=100 即可退出循环。

anobodykey 发表于 2018-4-20 10:23:10

楼主可以多分析一下,建议你看下该链接https://www.stmcu.org.cn/module/forum/thread-608277-1-1.html,同样是讨论Hal_Delay的溢出问题,其实你就会发现ST把uwTick设计成为32位无符号型是有意义的,至于你说的把它改成u8类型其实适用于8位单片机系统,但stm32是32位的单片机系统,所以溢出问题不影响你的延时

wolfgang2015 发表于 2018-4-20 10:49:21

HAL代码只是一个事例,具体情况具体分析,U32的循环完了,判断FF后又从0开始计数,或者直接忽略掉此处的溢出中断。循环往复了~~
页: [1] 2 3
查看完整版本: 质疑HAL库的延时函数HAL_Delay