STM32Cube FW_F1 V1.8.0 package breaks HAL time source init

As a hobby I’m working on a growbox controller which based on stm32 MCU. Yesterday I got STM32Cube MCU package update, as many times before I just upgraded package and project to latest version, as result firmware started to stuck in assert_failed().

It happens during call of SystemClock_Config() (defined in main.c) which in turn calls  HAL_RCC_ClockConfig(), which in turn calls HAL_InitTick(uwTickPrio) at Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c:947:

...
  /* Update the SystemCoreClock global variable */
  SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos];
 
  /* Configure the source of time base considering new system clocks settings*/
  HAL_InitTick(uwTickPrio);
 
  return HAL_OK;
}

When it happens uwTickPrio still have invalid interrupt priority, which is defined in Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c:80:

...
/** @defgroup HAL_Private_Variables HAL Private Variables
  * @{
  */
__IO uint32_t uwTick;
uint32_t uwTickPrio   = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */
...

Only one place where uwTickPrio can be updated is ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c:234:

__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  /* Configure the SysTick to have interrupt in 1ms time basis*/
  if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
  {
    return HAL_ERROR;
  }
 
  /* Configure the SysTick IRQ priority */
  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  {
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
    uwTickPrio = TickPriority;
  }
  else
  {
    return HAL_ERROR;
  }
 
  /* Return function status */
  return HAL_OK;
}

But this function is redefined in ./Core/Src/stm32f1xx_hal_timebase_tim.c:42:

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  RCC_ClkInitTypeDef    clkconfig;
  uint32_t              uwTimclock = 0;
  uint32_t              uwPrescalerValue = 0;
  uint32_t              pFLatency;
 
  /*Configure the TIM4 IRQ priority */
  HAL_NVIC_SetPriority(TIM4_IRQn, TickPriority ,0);
 
...

And doesn’t contain proper uwTickPrio initialization, as result it’s called with invalid TickPriority  and fails into assert_failed() during HAL_NVIC_SetPriority(TIM4_IRQn, TickPriority ,0) call.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>