cancel
Showing results for 
Search instead for 
Did you mean: 

SysTick not preempting other interrupts

danderle
Associate II

Hello,

I've got a very basic setup for an STM32G431KB/STM32G441KB where I use default interrupt priorities (verified all 0 in SBC and NVIC) for each exception in the vector table. I would therefore expect that a SysTick exception (-1) would preempt any other interrupts (irq > 0). However, when my code enters for example an EXTI3 or FDCAN1_IT0 ISR, the ISR is not preempted by SysTick, even though I see in the SBC register that SysTick is pending.

The problem is that my EXTI3/FDCAN1_IT0 ISRs rely on a global variable incremented by the systick ISR (1ms timer), and since SysTick ISR is not called, the code enters an infinite while loop.

I can get around this problem by decreasing the priorities of EXTI3/FDCAN1_IT0 to priority 1 and leaving SysTick at 0. Just to check, only writing 0 to SysTick prio in SBC doesn't solve the issue.

Is there something I'm overlooking here?

Thanks in advance!

5 REPLIES 5

>>I would therefore expect that a SysTick exception..

But that's not how it works on CM3/CM4 cores, it is not treated as an NVIC Interrupt like the other peripherals, its a system handler, but there is a setting to define its priority, and it fits in the same priority space as everything else.

If another level 0 interrupt is running the SysTick will only be serviced as you leave the current interrupt.

If you want it to preempt it needs to be in a group by itself.

SysTick should have the highest priority if you're relying on it for timeouts, like the HAL does. A better design would be to use a free-running 32-bit TIM for the purpose of getting a HAL tick number, but ST didn't chose to do that. In some releases the deprioritized it.

Also be conscious that callbacks are done in interrupt context, at the priority of the handler that called into the HAL for servicing. Don't put blocking code in callbacks.

Generally if you've got a lot of criticality in interrupt priorities, and spend a lot of time in other handlers that requires things constantly preempt, the design needs reevaluation. If the IRQ Handler can't leave immediately you should be deferring the work into a secondary task.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III

In addition...

The standard SysTick_Config function sets the systick priority to lowest.

So if you want high priority, set it after calling SysTick_Config.

If you use the ST HAL library, HAL_Init will fix the priority according to some defined macro. Or you can change the priority later.

Note that the timer used by the HAL library is not necessarily the systick, it can be any other timer.

danderle
Associate II

Thank you all for your replies! Just to clarify, I am not using HAL or RTOS in this design. I was trying to find reference to this preemption "problem" but I couldn't. Could any of you please provide a link where the fact that SysTick can't preempt lower priority interrupts by default is documented? Is it a settings related to priority groups? Is this only for CM3/CM4 (so CM0 and CM7 for example do this differently?)

It can preempt lower priority interrupts, but can't preempt interrupts of the same priority level. And that's the same for NVIC interrupts also.

Ah, that makes much more sense now. So if 2 interrupts have the same priority and they happen at the same time, the one lower in the vector table will be executed first. However, if they fire out of sync, the first to occur will run to completion before the next one can start, irrespective of the position in the vector table. Do I understand it correctly? @Piranha​