Description
The ST Hal makes extensive use of the HAL_Delay and HAL_GetTick for timing out operations. Normally, these functions use the SysTick interrupt to increment every millisecond - this remains true for the startup period of the STM32, as SysTick is turned on by HAL_Init and is not explicitly turned off until the common_hal_mcu_delay_us
is called, which sets the SysTick->CTRL register to 0 (typically the first instance of this function is in microcontroller __init__.c
). After SysTick is turned off, the HAL tick value will never increment and these functions will cause statements like the following to hang:
uint32_t tickstart = HAL_GetTick();
while ((HAL_GetTick() - tickstart) <= 100) {
// etc
This has a surprisingly low occurrence rate in normal operation, since timeouts don't tend to trigger unless something is actually wrong with a device setup, so this issue didn't turn up in testing right away. However, in the right circumstances it can cause an irrecoverable infinite loop in many different HAL modules. Should be fixed by overriding HAL_Delay and HAL_GetTick with new versions, but only after the RTC has been set up, since this issue triggers in the HAL RCC init functions.
Thanks @jepler for helping to locate this issue.