现有代码库部分文件调用HAL_GetTick()返回0但HAL_Delay()正常问题咨询
优先检查
HAL_GetTick及全局变量uwTick的重复定义
HAL库默认将SysTick计数全局变量uwTick定义在对应芯片系列的stm32fxxx_hal.c文件中,且HAL_GetTick()的默认实现也在该文件内。如果其他文件单独定义了同名的uwTick变量,或者自行实现了返回固定值的HAL_GetTick()函数,链接阶段会优先调用自定义版本,就会出现部分文件(直接调用hal.c内实现的文件)返回正常、其他文件返回0的问题。你可以全局搜索工程内HAL_GetTick的定义,确认是否存在多个实现。确认调用时机是否早于SysTick初始化
HAL_GetTick()的返回值依赖uwTick的计数更新,该变量只有在HAL_Init()调用、且SysTick定时器初始化完成后才会递增。如果返回0的调用位置处于时钟配置、SysTick初始化完成之前,返回0属于正常行为。你可以在两个调用位置分别插入打印,确认返回0的调用是否早于SysTick初始化流程。检查
uwTick的volatile修饰符是否被移除
HAL库默认给uwTick添加了__IO修饰(本质是volatile),避免编译器优化该变量的读取。如果工程修改了uwTick的定义移除了该修饰符,开启O2及以上等级优化后,编译器会将uwTick的读取缓存为初始值0,导致跨文件调用时始终返回0。你可以直接查看stm32fxxx_hal.c中uwTick的定义,确认修饰符完整。排除高优先级中断上下文的影响
如果调用HAL_GetTick()的位置处于优先级高于SysTick的中断上下文内,SysTick中断无法触发更新uwTick,会导致读取值一直不变。但这种场景下HAL_Delay()也会因为无法等待uwTick更新卡死,如果你对应位置的HAL_Delay()可以正常运行,可直接排除该问题。
内容的提问来源于stack exchange,提问作者Tim

