cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F101RD: Interrupt preemption not working

jansen
Associate II
Posted on October 03, 2014 at 16:52

System info: 8MHz external clock, 24MHz interrupt system clock.

Interrupt preemption is not working for me no matter the combination of priorities and priority groupings. My goal is to have a high speed timer interrupting every 0.1ms that doesn't get pushed round by other interrupts. Other interrupts include button and switch handlers via EXTIx inputs, UART interrupts for multiple serial inputs, and a couple other slow speed timers.

I'm using priority grouping 1, which gives me two priority groups, 0 & 1. I assume groups with lower priority are of higher preemption priority similar to interrupt priorities. Is this a good assumption?

My high speed timer uses TIM7 and is assigned to priority group 0, sub-priority of 0. This should be highest priority in the highest preemption priority group. All the other interrupts are in preemption priority group 1 with sub-priorities from 1 to 4. The TIM7 interrupt handler toggles a GPIO pin I can watch with an o-scope.

When I put this up on the o-scope and press buttons, I see TIM7 jitter around getting held off while the button handlers do their thing. The TIM7 interrupt is clearly not preempting the button handlers. Note, the button handlers do not disable the other interrupts via primask or basepri.

I feel I'm missing some fundemental setting here. What do I have to do to get preemption to work?

I've tried using SysTick instead of TIM7 and that gets held off, too. I don't see any means to assign SysTick to a priority group, unless the priority field for SysTick works the same as other interrupts.  Can SysTick be in a priority group or is it always in group 0? None of the ARM documentation indicates one way or the other.

Any help would be greatly appreciated! Thank you!

#stm32 #interrupts #preemption
18 REPLIES 18
chen
Associate II
Posted on October 06, 2014 at 17:44

Hi

''Determinism and latency is my concern, NOT execution order.''

Maybe I have not explained it very well.

You are trying to prove that a high priority ISR executes if 2 ISRs of different priority levels occur at the same tine, or close enough that they appear to be at the same time.

I suggested a test where you can check this by checking the order in which they executed.

Setting up for this test will be tricky.

Trying to explain this has made me think :

what if the delay you are seeing is due to the lower priority ISR executing and then being interrupted by the higher priority IRQ/ISR

jansen
Associate II
Posted on October 06, 2014 at 18:06

''You are trying to prove that a high priority ISR executes if 2 ISRs of different priority levels occur at the same tine, or close enough that they appear to be at the same time.''

NO, I'm trying to get my high priority interrupt to preempt my low priority interrupt.

I can demonstrate that preemption is not occurring by putting a GPIO line driven by the high speed, high priority interrupt on an o-scope and see it stop toggling while a slow, low priority interrupt handler executes.  The interrupt that should go off every 0.1ms stops for roughly 3.5ms while a lower priority interrupt is handled.

chen
Associate II
Posted on October 06, 2014 at 18:41

''NO, I'm trying to get my high priority interrupt to preempt my low priority interrupt.''

I understand. I am trying to suggest experiments to help determine what is going on.

As I said, I would not bother using ''

NVIC_IRQChannelSubPriority

''

I would just put ever ISR on a different ''

NVIC_IRQChannelPreemptionPriority

''

You have 240 of them to play with

''The NVIC supports:

• An implementation-defined number of interrupts, in the range 1-240 interrupts.

• A programmable priority level of 0-255 for each interrupt. A higher level corresponds to

a lower priority, so level 0 is the highest interrupt priority.''

''The interrupt that should go off every 0.1ms stops for roughly 3.5ms while a lower priority interrupt is handled.''

That suggests to me that the lower priority ISR is not clearing the IRQ active bit but you said

''I just changed to clear interrupt flags first in all the interrupts.  It did not help...''

so it is difficult to understand what is going on here.

stm322399
Senior
Posted on October 07, 2014 at 09:11

J,

I tried to demonstrate preemption on F100, and surprise ... it worked. I configured my test the same way you did (2 groups). Let's try to see what make that you cannot get the same result:

* My target is F100 while yours is F101. IMHO it shall not change anything, both have CM3 inside. Just hoping F101 has no bugs ... I also have F103 to test, just in case it will help.

* I only used TIM7(fast) and TIM3(slow) to make my demonstration. The former has 100µs period, the latter 1ms. Interrupt handlers respectively uses a dedicated GPIO to generate a pulse, the TIM3 pulse takes a long time on purpose (300 to 400µs). The TIM7 pulse occurs even when TIM3 pulse is active, preemption works.

* I run from sram

* Never touched BASEPRI

* Checked that when TIM7 and TIM3 are in the same group, no preemption occurs.

It is very important to setup a use case as minimalistic as possible, forget about other UARTS, forget SysTick (I shall work between two timer), keep only two timers.

jansen
Associate II
Posted on October 08, 2014 at 20:54

I've been off on other fires today so far.  When I get a chance, I'll implement a GPIO line to the o-scope on the slow interrupt to validate, assuming I can stir up hardware not in an enclosure....

If I'm barking up the wrong tree and preemption is working that means my TIM7 (or SysTick) interrupt handler is taking a long time or a high priority event is occuring (NMI or HardFault).  I've looked at this before.  The NMI and HardFault handlers are empty functions.  The TIM7 (SysTick) handler doesn't contain any loops or overt delays, and doesn't do much.  Hmm....

Thank you all for the help!  
tomidevil
Associate
Posted on October 14, 2014 at 16:39

Hello,

i'm faceing exactly the same problem. STM32F103VET6. TIM3 ISR should preempt TIM4 ISR, but it is just not working. It will be performed right after TIM4 ISR finished. I tried every possible priorities, checked the NVIC register values - everything seems to be right..

Did you find any solution?

Thank you!

stm322399
Senior
Posted on October 14, 2014 at 16:46

Did you tried to write the smallest piece of code demonstrating you problem ? Throw away any setup that is not necessary to the test, and when it work (or more likely not work) post your code here.

Posted on October 14, 2014 at 17:12

Post content of relevant registers (SCB->AIRCR, relevant NVIC->IP[]).

JW
jansen
Associate II
Posted on October 15, 2014 at 22:58

Currently, I'm working around this bug.  I've slowed my timer down to the point of very little contention with other interrupts.  This is a short term workaround.  When I get a moment to breath, I plan on testing this in more detail so I can utilize preemption.  If it really doesn't work as advertised, then I'll have to make major changes....