AnsweredAssumed Answered

[bug report] Bug in HAL (SPL) delay function

Question asked by khazanskii.roman on Mar 12, 2014
Latest reply on Mar 31, 2017 by Pakula.Lyle
Setup:

I've just generated code for stm32f407 using the latest STM32CubeMX. Here's the generated code for delay function in file stm32f4xx_hal.c:


void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t timingdelay;
 
  timingdelay = HAL_GetTick() + Delay;
  while(HAL_GetTick() < timingdelay)
  {
  }
}


It's fairly simple, HAL_GetTick returns a value of uwTick - variable that is incremented in SysTick interrupt handler.

Bug Description:

When the value of variable uwTick becomes large enough (i.e. adding Delay will overflow uint32) delay function will not work correctly, because expression "HAL_GetTick() < timingdelay" will immediately be false.
That results in no delay at all.



Example:

Consider
uwTick = 0xFFFF FF00and Delay = 0x101
Then:
timingdelay = 0xFFFF FF00 + 0x101 == 0x01

Then while(HAL_GetTick() < timingdelay) is ( 0xFFFF FF00 < 0x01 ). This is already false and while is not executed. No delay is performed!

Comment:
This bug can be real pain, because it will work only when overflow of uwTick is near (or delay is really large). If one had uwTick incremented every millisecond (seems to me like a reasonable value), bug can accure in about 47 days from reset.

Solution:
That's easy enough:


uint32_t startTime = HAL_GetTick();
while( HAL_GetTick() - startTime <= Delay);

If we compare the differencies between moments of time and Delay - we are okay (as long as Delay is not bigger than 0xFFFF FFFF, but that's sort of unrealistic and can be guaranteed by assert); overflow will not affect it.

Outcomes