questionS about "how to disable a particular interrupt"

ig-or

Active member
Hello! Would you please help me with the following:

I'm using Teensy4.1 with latest teensyduino library. In a code, I'm running a function "myPeriodicFunction" every two millisecond, following way:

Code:
EventResponder er;
er.attachInterrupt(myPeriodicFunction);
MillisTimer mt;
mt.beginRepeating(2, er);

And this looks like working, function is running every two milliseconds.

Now I need to update some data structure for this function: change about 8 numbers, so myPeriodicFunction would use those new parameters. I need this from the "main", not from the interrupt. And I'd like to pass all the parameters "at once", not one by one.

What could be the correct way to do this? I do not want to disable all the interrupts in "main". Can I disable only just this ('low priority?') interrupt? And after I enable it, will "myPeriodicFunction" be called right after this (right after "enable_irq")?
Should I use "__NVIC_DisableIRQ" and if yes, how to do this correctly? Or, maybe better not to disable interrupts but use __STREXW, as I noticed in micros() function ? (But this latter case looks not safe sometimes.. like if "main" would constantly updating the structure, and then interrupt will occur, and it see that "structure is updating right now and what's next? looks like it may be that in this case irq (myPeriodicFunction ) will never use updated structure.)

Also I noticed that "void attachInterrupt(EventResponderFunction function, uint8_t priority=128)" does not use its "priority parameter.
Instead, there is a "SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority"
How to correctly setup an interrupt with slightly higher priority then this one?



Best regards!
 
The disable seems the right thing.

Indeed __STREXW is safe for READ. Any write could be interrupted and repeated partway though.
 
What you are doing should be more common. Ie don't turn off any more interrupts than necessary.

Also, don't turn back on interrupts that were off from previous code. Unfortunately, code like this is common:

__disable_irq();
...
__enable_irq();
 
I second most all of the above comments.

Also depending on what you are using for the interrupt, you may have to understand, that maybe one interrupt may be servicing more than one thing. Example if you do
an attachInterrupt(pin, myisr);
On T4.x there is one interrupt servicing all of the pin interrupts, so if you disable that interrupt you are disabling all pin interrupts.

But if you are using a very specific interrupt, where you do an: attachInterruptVector(...), then as mentioned you can disable that one.

Also sometimes how to handle this may depend on if you are simply not wanting the functionality within the interrupt not to happen or if you are disabling as to try to reduce the overhead...

Otherwise I might just do a quick and dirty solution, like:
Define a variable like: volatile bool data_update_in_progress = false;

then set this variable true before you start updating your stuff and set it back to false when done.

Then at start of your interrupt code: simply test for this being set and return without processing anything.
 
> Define a variable like: volatile bool data_update_in_progress = false;

My understanding is that the compiler might re-order code around this, perhaps putting the set to true after your updates. Or maybe not - the 8 numbers are also volatile?

This may a generally better declaration for variables shared with an ISR:

static volatile std::atomic<unsigned> data_update_in_progress (0);


Here are other gotcha cases:

volatile unsigned *flag; // shared variable set by ISR

if (flag != NULL) {
// interrupt could happen here
do something with flag that assumes it isn't zero
}


Or

volatile unsigned counter=0; // incremented by ISR

do something with counter
// interrupt could happen here, causing a count to be missed
reset counter to zero

Maybe x = __atomic_exchange_n (&counter, 0, __ATOMIC_SEQ_CST) for this one?
 
Last edited:
defragster , jonr, KurtE, thank you for your help.
I looked a few libraries, how similar things are implemented by Paul and others, and it looks like for my case it maybe better to go simple way: enable/disable all interrupts, just remember not to do this often.
 
Back
Top