Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

11.1.0 regression when the firmware is loaded from a bootloader #118

Open
escherstair opened this issue Jan 10, 2025 · 4 comments
Open

11.1.0 regression when the firmware is loaded from a bootloader #118

escherstair opened this issue Jan 10, 2025 · 4 comments
Assignees

Comments

@escherstair
Copy link

escherstair commented Jan 10, 2025

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.

@cbusquet-expressivee
Copy link

cbusquet-expressivee commented Jan 10, 2025

Quick questions :

did the bootloader use FreeRTOS or is it BareMetal ?
did it (the bootloader) disable the fautive interrupt before launching the application ?

I run in this smae sort of issue, when i restart my Apps which use TIM6 and FreeRTOS with my bare metal BootLoader.

@escherstair
Copy link
Author

did the bootloader use FreeRTOS or is it BareMetal ?

The bootloader uses FreeRTOS.

did it (the bootloader) disable the fautive interrupt before launching the application ?

This is the code that clears the interrupts before jumping to the application:

   //Disable all enabled interrupts in NVIC
   NVIC->ICER[0] = 0xFFFFFFFF;
   NVIC->ICER[1] = 0xFFFFFFFF;
   NVIC->ICER[2] = 0xFFFFFFFF;
   NVIC->ICER[3] = 0xFFFFFFFF;
   NVIC->ICER[4] = 0xFFFFFFFF;
   NVIC->ICER[5] = 0xFFFFFFFF;
   NVIC->ICER[6] = 0xFFFFFFFF;
   NVIC->ICER[7] = 0xFFFFFFFF;

   //Clear all pending interrupt requests in NVIC
   NVIC->ICPR[0] = 0xFFFFFFFF;
   NVIC->ICPR[1] = 0xFFFFFFFF;
   NVIC->ICPR[2] = 0xFFFFFFFF;
   NVIC->ICPR[3] = 0xFFFFFFFF;
   NVIC->ICPR[4] = 0xFFFFFFFF;
   NVIC->ICPR[5] = 0xFFFFFFFF;
   NVIC->ICPR[6] = 0xFFFFFFFF;
   NVIC->ICPR[7] = 0xFFFFFFFF;

   //Disable SysTick module
   SysTick->CTRL = 0;
   //Clear its exception pending bit
   SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;

   //Disable individual fault handlers
   SCB->SHCSR &= ~(SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk |
      SCB_SHCSR_MEMFAULTENA_Msk);

@cbusquet-expressivee
Copy link

last suggestions, could you verify the status of TIM6 before launching App, then if it run stop it. (and ask why ?)

@escherstair
Copy link
Author

This is the status of TIM6

Image

This is (a subset of) NVIC

Image

I haven't find the origin for this issue yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants