CMSIS-FreeRTOS icon indicating copy to clipboard operation
CMSIS-FreeRTOS copied to clipboard

11.1.0 regression when the firmware is loaded from a bootloader

Open escherstair opened this issue 9 months ago • 6 comments

I open this issue as a follow-back of this one #65, since I see that the same issue is there with FreeRTOS 11.1.0. The last release that works properly is 10.4.6. Starting from FreeRTOS 10.5.1 I saw this issue. I summarize here what I wrote in issue #65

I have an application running on STM32H725, with peripheral configuration code generated by STM32CubeMX 6.13.0. I think that STM32CubeMX is important here (I will describe the reason later) This application can be compiled in two different ways:

  • to be executed directly (out of the Cortex-M reset)
  • to be started from a custom bootloader running from user flash (i.e., vector table relocation, ...)

Everything works fine with CMSIS-FreeRTOS 10.4.6, but when I upgraded the pack to 11.1.0 I see a regression:

  • when the application is executed directly, everything is ok

  • when it's started by a bootloader, this is the call chain

    main() >> HAL_Init(); >> HAL_InitTick(TICK_INT_PRIORITY)
    

    where

    #define  TICK_INT_PRIORITY            (15UL) /*!< tick interrupt priority */
    

    Then

    /*Configure the TIM6 IRQ priority */
    if (TickPriority < (1UL << __NVIC_PRIO_BITS))
     {
       HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0);
    
       /* Enable the TIM6 global Interrupt */
       HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
       uwTickPrio = TickPriority;
      }
    else
    {
      return HAL_ERROR;
    }  ```
    
    and after that the function `void TIM6_DAC_IRQHandler(void)` is continously called and nothing else.
    
    

I suppose some issue with interrupt priorities.

Here is what I found out: STM32CubeMX 6.13.0 generates source code to use TIM6 as a time base source.

I saw that inside stm32h7xx_hal.c

__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

is defined as a __weak function and it's reimplemented by source code generated by STM32CubeMX 6.13.0 in stm32h7xx_hal_timebase_tim.c

In stm32h7xx_hal.c I see

/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
  HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
  uwTickPrio = TickPriority;
}
else
{
  return HAL_ERROR;
}

In stm32h7xx_hal_timebase_tim.c I see

/*Configure the TIM6 IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
  HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0U);
  /* Enable the TIM6 global Interrupt */
  HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
  uwTickPrio = TickPriority;
}
else
{
  return HAL_ERROR;
}

/* Enable TIM6 clock */
__HAL_RCC_TIM6_CLK_ENABLE();

You can see the different timer used as a base (SysTick vs TIM6), but this is not an issue by itself. Most important, see that in stm32h7xx_hal_timebase_tim.c there is

/* Enable the TIM6 global Interrupt */
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);

As soon as this is called, the callback void TIM6_DAC_IRQHandler(void) is called immediately, and I think this is because the clock has been already enabled by the bootloader, and/or a TIM6 interrupt is pending.

Not sure why everything work with CMSIS-FreeRTOS 10.4.6, but the code generated by STM32CubeMX doesn't convince me. I'll go on with my investigation.

escherstair avatar Jan 10 '25 09:01 escherstair