cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMX fixes timer interrupt priority for HAL timer if RTOS enabled?

willcfj
Senior

I'm doing my first non-trivial program using FreeRTOS, so suspect this is a newbie question. Besides the timer for FreeRTOS (using SysTick), I need a timer for the HAL (using TIM7), and another timer for some high speed audio DSP routines (using TIM6 and triggering the DAC/ADC). The audio interrupt needs to be the highest of the three. Before the RTOS that was easy, I just make sure TIM6 had a higher priority than HAL SysTick.

FreeRTOS needs to use SysTick and there are lots of warnings about not sharing the HAL and FreeRTOS timer. No problem. I just told CubeMX to use TIM7 as it's timebase instead. Once I do that, however, CubeMX fixes the interrupt priority for TIM7 to be 0 and it can't be altered. I need it higher than 0 so I can have TIM6 for the audio work be the highest priority. With TIM7 fixed at 0, I can't do that.

Since CubeMX is going out of its way to do this, I assume there is a reason. Is it trying to stop me from doing something bad I don't understand? I do need an interrupt higher priority than the HAL's timebase for sure, and before adding FreeRTOS had ho problem doing this. I even tried a dummy configuration without FreeRTOS using TIM7 for the HAL timer interrupt and still could change it's priority just fine. It is only if FreeRTOS is enabled that TIM7's priority gets fixed.

Thanks in advance. I'm on the most current version of CubeMX (5.3.0)

will

26 REPLIES 26
Tilen MAJERLE
ST Employee

@willcfj​ Interrupt level 0 is highest possible.

Normally, Systick uses lowest interrupt (assuming 4-preemption bits) of 15 [Higher number = Lower priority].

Read this useful post: https://www.freertos.org/RTOS-Cortex-M3-M4.html

Hope it is clear,

Tilen

willcfj
Senior

Thanks Tilen: Yes, since FreeRTOS is using SysTick, it is at the lowest priority (15 for me). That part is OK. The problem I'm running into is the timer I chose for the ST HAL (TIM7 in my case) is being forced to level 0 (highest) by CubeMX and not changable. I need another interrupt to be higher priority than the HAL and CubeMX won't let me do this. The tie-in with FreeRTOS is it only forces the HAL timer to level 0 if I enable FreeRTOS.

I have gathered a lot of links on FreeRTOS, but not seen that one yet. That was quite helpful on understanding the configMAX_SYSCALL_INTERRUPT_PRIORITY variable. I was having trouble understanding its significance.

willcfj
Senior

Just checking back on this. I plan on over-writing the CubeMX-generated code for the timer tick but really wondering if there is a reason it is forcing this.

Always first assume your code is in error before others! 🙂

will

WBOUG
Senior

Hi @willcfj​ ,

I need your ioc file please.

Best Regrads,

Wael

willcfj
Senior

Wael:

Sure! Hopefully attached. I noticed this on my regular project, but was able to easily reproduce it with a demo project IOC file just to be sure it wasn't something else I was doing. Steps were:

  • Selecting STM32H750 in CubeMX (my chosen part) as a new chip
  • Got to SYS menu and select Timer7 for the timebase source
  • Go to NVIC menu and slelct a non-zero interrupt priority for TIM7 (it isn't gray'd out, so I can)
  • Go to FreeRTOS and enable it
  • Go back to NVIC menu and now TIM7 is set to interrupt priority 0 and gray'd out, so not changable.

will

willcfj
Senior

Just pinging again on this issue. I can't see any explanation other than a CubeMX bug and will find a way to override it at the point where it starts to create issues for my project.

will

I finally encountered the situation where this issue mattered, I was trying to set a signal from a HAL timer initiated piece of code and so had the interrupt priority inversion issue which locked things up. The command to fix it was simple. I was using TIM7 for the HAL timer, so it was

   /* Hack to override CubeMX fixing the HAL Timer to interrupt priority 0 */
   HAL_NVIC_SetPriority(TIM7_IRQn, 6 ,0);

By trial and error, the place to put it seems to be in main() after all the MX_???_Init() routines in the USER CODE 2 area. I tried earlier just after HAL_Init() as that is where it is set, but something elsewhere seems to override it in the MX_???_init() routines. The reason for level 6 is unique to my application, main thing is for it to be a higher number (lower priority) than the LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY parameter in the FreeRTOS Config parameters section in CubeMX. The default for that is 5 and I'm choosing not to mess with it.

I still worry that there is a real reason CubeMX fixes the HAL timer to level 0 if FreeRTOS is enabled and it isn't just a bug. At least for now I got the expected problem because of the setting and setting the timer interrupt priority to what I think it should be fixes the problem too. If I discover any unintended consequences, I'll post them.

will

@willcfj​ R&D team is aware and will take a closer look.

Hello @willcfj​ 

- FreeRTOS always uses Systick as its time base

o So there are priority settings specific to Systick (note: we are talking about the SystickHandler function behind this)

- The fact that the SYS timebase is changed to set a timer, seems to require a prio setting for this timer

o But also one for systick (because FreeRTOS will always use systick for its time base)

What we fix on the stm32cubeMx side, as timebase, is the one of the IP SYS

- By default, SYS shares as timebase, Freertos' timebase, "systick".

o and it's not the healthiest setting (hence the pop-up when generating the code, which recommends choosing a timer)

- We can, therefore, set, aside stm32cubeMx, a timer to have a timebase specific to our world "HAL".

When a task has the status Running, the processor executes the task code. When a task has the status Not in progress, the task is in standby, its status having been saved. It is therefore ready to resume execution the next time the planner decides that he or she should enter the Running state. When a task resumes execution, it does so from the instruction it was about to execute the last time it was in the Running state.

Best regards,

Nesrine