cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt Nesting on STM32F3Discovery

keepcoding
Associate II
Posted on May 30, 2014 at 15:15

Hi

Is there a way to disable interrupt nesting (preemption) on the STM32F3Discovery? By default, an interrupt seems to preempt a currently executing ISR. But I want the ISRs (especially those of DMA and EXTI interrupts) to be executed atomically. How can I achieve this? Thanks keepcoding [edit] ok, I just found something:

// code before critical section
__set_BASEPRI(6 << (8 - __NVIC_PRIO_BITS));
// critical section
__set_BASEPRI(0U); // remove the BASEPRI masking
// code after critical section

So it looks like there is no such thing as atomicity in an ISR on the STM32 without disabling interrupts manually. Question: Do I potentially miss an interrupt during the time span when the interrupts are disabled or will it just be serviced after the ISR (when interrupts are reenabled)?
5 REPLIES 5
chen
Associate II
Posted on May 30, 2014 at 16:01

''But I want the ISRs (especially those of DMA and EXTI interrupts) to be executed atomically. How can I achieve this?''

This is done by carefully arranging the IRQ priority order. Higher priority ISR cannot be interrupted by lower priority ISR.

''So it looks like there is no such thing as atomicity in an ISR on the STM32 without disabling interrupts manually.''

There is no such thing in most processors! Higher priority IRQ/ISRs will always interrupt lower priority ISRs. On some (and I am thinking about the good old 68K) processor, you can manually disable all IRQs while in the ISR.

There does not seem to be a way of doing this easily in the ARM Cortex processor.

''Do I potentially miss an interrupt during the time span when the interrupts are disabled or will it just be serviced after the ISR (when interrupts are reenabled)?''

IRQs are 'queued' in priority order. Highest priority IRQs are serviced first until there are no IRQs left.

Only 1 IRQ per peripheral device can be queued so it is possible to say miss a USART IRQ if it is not serviced in time.

keepcoding
Associate II
Posted on May 30, 2014 at 17:27

''This is done by carefully arranging the IRQ priority order. Higher priority ISR cannot be interrupted by lower priority ISR.''

That's not what I want. I want no ISR to be interrupted, all have the same priority. They shall be executed in the order they arrive. 

''IRQs are 'queued' in priority order. Highest priority IRQs are serviced first until there are no IRQs left.''

Ok, but does this mean an ISR will never be interrupted

if all interrupts have the same priority

?

If two interrupts of the same priority are queued, which one is executed first?
chen
Associate II
Posted on May 30, 2014 at 18:01

Hi

''

That's not what I want. I want no ISR to be interrupted, all have the same priority.

''

It is unwise to have all IRQs at the same priority level.

''

They shall be executed in the order they arrive.

''

I am not sure if this is possible given the facilities in the processor.

''

Ok, but does this mean an ISR will never be interrupted

if all interrupts have the same priority

?''

Yes, IRQs of the same priority cannot interrupt each other.

However, it is unwise mainly because it raises the probability of missing IRQs.

''

If two interrupts of the same priority are queued, which one is executed first?

''

The first IRQ which triggered.

However, the order (if more than 3 IRQs) after that is undefined. Another reason to not have all IRQs at the same priority level.

The whole point of IRQ priority levels is to try and guarantee IRQ execution order.

IRQ priority levels also help to maintain system latency, by having important peripheral IRQs at higher priority - it helps to make sure those IRQs will be serviced first.

keepcoding
Associate II
Posted on May 30, 2014 at 18:32

Thanks a lot for your help! That is exactly what I was looking for.

[edit]

One last question: Is each interrupt pushed onto the stack or is this 'queueing' done in hardware (just by setting some bits)? What I wonder is, does an interrupt of lower or the same priority as the currently handled interrupt stall the execution of the program by a few cycles or is there no overhead involved?

[edit2]

I just found the ARMv7 system architecture description (which is implemented in the STM32F3). The document says that ''when multiple exceptions have the same priority number, the pending exception with the lowest exception number takes precedence''. The way I understand this is, if e.g. a DMA IRQ and a EXTI 1 IRQ are pending and have the same priority level, the EXTI 1 will always be executed first. 

So it looks like the system does NOT keep track of which IRQ came in first, it rather looks at the exception number... Or am I wrong? 
chen
Associate II
Posted on May 30, 2014 at 19:02

Hi

'' Is each interrupt pushed onto the stack or is this 'queueing' done in hardware (just by setting some bits)? ''

I think it is done in hardware.

'' or is there no overhead involved?''

There is overhead involved. It is quoted both by ARM and ST (depending on whether it is an ARM core or peripheral IRQ).

''So it looks like the system does NOT keep track of which IRQ came in first, it rather looks at the exception number... Or am I wrong? ''

That is correct. It is all to do with Exception number and the priority assigned to it.

If you do have all the IRQs at the same priority level, there is 'sub priority' levels.

Or at least the Standard peripheral library provides :

' NVIC_InitStructure . NVIC_IRQChannelSubPriority '

The information for this is in the ARM reference manuals.

There are 250 priority levels - so I do not understand why sub priority levels are needed!?! (but what do I know).