Skip to main content
Parmin Nayani
Associate III
March 4, 2022
Question

HAL_Delay counter wrap problem. in HAL_Delay current timer count is read first (tickstart = HAL_GetTick()) and the function waits till (while((HAL_GetTick() - tickstart) < wait)) the difference is equal or greater than given value. What happens if

  • March 4, 2022
  • 5 replies
  • 3345 views

current tick count is say 0x0fffffffff (just 15 short of an over flow) and if my delay (wait) is say 20. Running count will rollover after 15 ticks and becomes 0. The new comparison will 0-0x0fffffff. Will the delay still work? I guess not. Your valuable comments please? Thank you.

    This topic has been closed for replies.

    5 replies

    LCE
    Principal II
    March 4, 2022

    I guess you mean tickstart = 0xFFFFFFF0 ?

    Anyway, it's a 32 bit CPU working with 32 bit variables if not told otherwise, so I guess that also the result of (HAL_GetTick() - tickstart) will overflow, so that 1 - 0xFFFFFFF0 -> 0x11

    a) it shouldn't be too hard to test that unsigned 32 bit math,

    b) the HAL_Delay function is declared as "__weak", so you could easily write your own HAL_Delay.

    Parmin Nayani
    Associate III
    March 5, 2022

    Hi,

    Yes, tickstart = 0xFFFFFFF0. Made a mistake while typing. So the original code HAL_Delay has an issue!! The issue is, our controller is never reset or switched off. It is ON 24X7 so it is possible that an overflow will occur. I have not calculated but 1 mSec with 32 bit number, should wrap in some days (will check). Thank you for your time. Best regards.

    LCE
    Principal II
    March 7, 2022

    49.7 days

    Anyway, there is no problem with that function, just try it in code and set the SysTick manually to check what happens, if you don't believe anybody here... ;)

    TDK
    March 4, 2022

    Yes, it works.

    uint32_t are the same size as the native registers, which means the overflow will work as expected/desired here.

    The same would not be true for uint16_t values as they will be promoted to integers (int32_t) in order to do the comparison.

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    Parmin Nayani
    Associate III
    March 5, 2022

    Hi,

    Thanks for the reply. Whether it is a 16/32/64 bit value overflow will occur sooner or later if the controller is ON continuously. The HAL delay routine does not take into account wrapping of the systick timer counter. We need to write a separate code to take into account the warp and overflow issue. Regards

    Tesla DeLorean
    Guru
    March 4, 2022

    The cited code works properly, using uint32_t number space properly

    Whereas naive code like this does NOT.

    finish_time = HAL_GetTick() + timeout;

    while(HAL_GetTick() < finish_time);

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Parmin Nayani
    Associate III
    March 5, 2022

    Hi,

    Whatever is the size of the variable overflow will occur if the controller works long enough without a reset. therefore "The cited code works properly, using uint32_t number space properly" this may not hold. The only option is to write another delay function which will take into account the wrap problem. Thanks.

    TDK
    March 5, 2022

    > So the original code HAL_Delay has an issue!!

    No it doesn't.

    > The HAL delay routine does not take into account wrapping of the systick timer counter.

    Yes it does.

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    S.Ma
    Principal
    March 6, 2022

    This works with all timer captures as well.

    16 bit timer, get 0x0000-0xFFFF will yield 1 if the substract is clipped to 16 bits.

    What is a bit more tricky is to extend the timer bit length say from 16 bit to 32 bit by interrupt, and caring to what happen at the rollover update interrupt event. That might become the next question down the road....