Skip to main content
willcfj
Associate III
October 24, 2019
Question

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

  • October 24, 2019
  • 14 replies
  • 9996 views

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

This topic has been closed for replies.

14 replies

Tilen MAJERLE
ST Employee
October 25, 2019

@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
willcfjAuthor
Associate III
October 25, 2019

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
willcfjAuthor
Associate III
October 27, 2019

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

Visitor II
October 28, 2019

Hi @willcfj​ ,

I need your ioc file please.

Best Regrads,

Wael

willcfj
willcfjAuthor
Associate III
October 28, 2019

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
willcfjAuthor
Associate III
November 9, 2019

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

willcfj
willcfjAuthor
Associate III
November 15, 2019

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

Tilen MAJERLE
ST Employee
November 15, 2019

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

Nesrine.JLASSI
Visitor II
December 6, 2019

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

willcfj
willcfjAuthor
Associate III
December 7, 2019

Hello Nesrine and thank you for the reply:

Fully understand and OK with FreeRTROS using SysTick and the priority level for SysTick that then calls the RTOS functions. That all makes sense. What I think I'm doing different is I have the RTOS running from a different timer than the HAL. The RTOS (using SysTick) is running at 100Hz and the HAL timebase (using TIM7) needs to be at 1000Hz. That in itself should be OK. From a routine called by HAL timebase interrupt, I do need to make an RTOS call. Because of that, I need to satisfy this RTOS requirement from the link above (https://www.freertos.org/RTOS-Cortex-M3-M4.html:( (about half way down)

Relevance when using the RTOS

FreeRTOS functions that end in “FromISR�? are interrupt safe, but even these functions cannot be called from interrupts that have a logical priority above the priority defined by configMAX_SYSCALL_INTERRUPT_PRIORITY (configMAX_SYSCALL_INTERRUPT_PRIORITY is defined in the FreeRTOSConfig.h header file). Therefore, any interrupt service routine that uses an RTOS API function must have its priority manually set to a value that is numerically equal to or greater than the configMAX_SYSCALL_INTERRUPT_PRIORITY setting. This ensures the interrupt’s logical priority is equal to or less than the configMAX_SYSCALL_INTERRUPT_PRIORITY setting.

This seems straight forward and makes sense, but after setting up SysTick for RTOS and then setting up TIM7 for the HAL, CubeMX forces the interrupt priority for TIM7 to be 0. configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5. That does not meet the requirement in bold above and the RTOS hangs as predicted. The "hack" I have above fixes the issue, changing the priority for TIM7 to 6.

I'm relatively new to using an RTOS, so reluctant to just dismiss it as a CubeMX bug and asking if I'm doing something wrong. It seems what CubeMX is doing is violating the RTOS's clearly documented requirements, and if so, is a bug. I believe being able to make an RTOS call from a routing running from the Hal timers is something that should be expected and allowed. Yes, if I were dumb and tried to make an RTOS call every timer tick that would be bad, but I'm not doing that! :)

Thank you for the attention. With the above fix, the code has been working fine with no observed bad side effects.

will

Piranha
Principal III
December 7, 2019

Read that bolded+underlined sentence and the next sentence carefully! I'll fix your previous conclusion:

> That is if you have any ISR that needs to make an RTOS call, the priority of that ISR must not be higher (lower number) than the LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY level specified in the RTOS.

willcfj
willcfjAuthor
Associate III
December 7, 2019

Piranha:

OK, I know you are a lot more expert than me, so now worried there is something I don't know. The bold sentence above says the priority must be numerically equal to or greater than LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, so >=5, right? My problem is CubeMX fixes the Timer ISR to interrupt priority 0. If I'm confused it is very fundamental! There are other places that say the same thing too. Another good example is UM1718 section 4.4.14, where they even show an example related to RTOS support. it says: "In this case, all the interrupt service routines (ISRs) that are calling the interrupt safe FreeRTOS APIs must have a priority lower than the priority defined in the LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY parameter (the highest the value, the lowest the priority). The check in the corresponding checkbox guarantees that the restriction is applied." If you check the box that says this ISR makes RTOS calls, the only available priorities are >=LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY.

Thanks in advance for your answers. RTOS programming is new to me, so trying to understand. This seems pretty fundamental and besides the conflict between CubeMX and lots of documentation, with the TIM7 priority set to 0, the RTOS hangs, but not when i override CubeMx in my source and set a priority of 6 all works fine. So even the code seems to agree with the docs.

will

Piranha
Principal III
December 7, 2019

One thing was that you missed "not" in that sentence, but I suppose that it's a simple error not wrong understanding. The other thing, I now see that you're missing, is that the HAL tick ISR (TIM7 in your case) is not supposed to call any RTOS functions. If it doesn't call those, then that priority rule doesn't apply to it and from FreeRTOS perspective it can have any priority.

willcfj
willcfjAuthor
Associate III
December 7, 2019

Piranha:

OK, that may be the official answer, I should not be making RTOS calls from code being called by the HAL Tick ISR. I have some code from a pre-RTOS project that does some status polling based on the HAL timer tick. It is polling the status of some audio DSP code that needs to be higher priority than the timer tick as I can't afford any timer tick code to preempt the audio code.

I do see that if somewhere in code that isn't mine there is an assumption that HAL code can interrupt RTOS code, something might break. Time to think about re-factoring the code...

will

Piranha
Principal III
December 7, 2019

You can be sure that HAL doesn't call any RTOS APIs because it's not RTOS aware in any way at all. Actually that is one of the two reasons why they implemented a separate tick counter independent RTOS. The other reason is that they use timeouts in interrupt handlers and therefore require HAL tick ISR to be with a higher priority than other ISRs. That is ridiculously stupid design, but that's what you get from a brainless code monkeys and blind management...