CMSIS-FreeRTOS
CMSIS-FreeRTOS copied to clipboard
11.1.0 regression when the firmware is loaded from a bootloader
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.