PIT and External Interrupts

Status
Not open for further replies.

At_Giza

New member
Hello

I have some questions about using external interrupts simultaneous with Interval Timer library.
1. What will happen when uC is executing ISR called by PIT and during this task an external interrupt occurs and what will happen when external interrupt occured first and PIT is trying to interrupt it?
2. Will uC execute the ISR called by external interrupt or will it has to wait till the function called by PIT?
I 've seen somewhere (i don't know if it's true) that in Arduino boards based on Atmega ,while using Arduino's library ,if an external interrupt occurs ,when uC is executing another ISR called by external interrupt, then it has to wait till the previous one ends. I would like to know how does using both features can affect each other.
3. Does the result of such occurrence will be the same in regards of all actually maintained 32-bit Teensy boards.

I would be really thankful for the answer :).
 
You will get probably better answers, but Teensy (arm-based) has a hierarchy if interrupts. So, an ISR can only be interrupted by an other Interrupt with higher priority.
 
As @WMXZ mentioned, each interrupt on a Teensy 3.x, 4.x... have a priority that can be set using the NVIC_SET_PRIORITY(irq_num, priority)
If another interrupt comes in and it has a higher priority (lower priority number), then the current running interrupt will it interrupt that currently running interrupt. When the interrupt returns from an interrupt and there are still pending interrupts, it will then call of that interrupt handler.

With Interval timer, code there is a priority method that you can call that will set the interrupt priority for the underlying timer.
 
Indeed it all depends on the configured priority level of each interrupt. The priority numbers are from 0 to 255, where smaller numbers mean higher priority. The hardware only implements 16 discrete levels (and Teensy LC has only 4 levels), but 8 bits is used so future hardware could give more levels for finer control and remain compatible.

By default, all interrupts use priority 128, except SysTick which is 32. Some libraries configure their interrupts higher priority, some to lower priority. The audio library is the main use where an interrupt is run at much lower priority, so the DSP math needed to keep the audio streams running is able to interrupt your main program, but almost all libraries which need rapid access to hardware are able to interrupt the audio processing. As a general rule we never use 0 to 31 in any libraries, which gives you the ability to use the top 2 priorities in your program.

If another interrupt or equal or lower priority occurs while your interrupt is running, it will wait and run after yours has completed. Or if multiple interrupts at lower priority than your occur while yours is running, the highest priority (lowest numerical setting) will run after yours is done, and the hardware will keep running them one after another in their priority order. The hardware has a nifty "tail chaining" optimization it does automatically in this scenario, where it avoids fully restoring all the registers and then just saving them again as the next interrupt starts. It only does all the restore work when actually returning to code it interrupted.

If another interrupt with higher priority occurs while yours is running, it will interrupt your interrupt. Because the hardware supports 16 discrete levels, theoretically you could have a situation where 16 interrupts have nested, where the one at level 16-31 will run after the one at level 0-15 finishes, and then the one at level 32-47 will run after those, and so on.
 
Thank you very much. You have explained me a lot.
So as I understand, if I want to set an interrupt for a pin, which is capable of it and I want to change the priority of this interrupt, then I only need to use function:
attachInterrupt(digitalPinToInterrupt(pinNumber), someFunction, FALLING); and then according to the type of a 32-bit board I am using and pin number, I need to choose the right irqnum, which I found in imxrt.h or kinetis.h and proper priority level value and put those values in a macro: NVIC_SET_PRIORITY(irqnum, priority); and it would just work? Am i right?
 
Status
Not open for further replies.
Back
Top