Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: questionS about "how to disable a particular interrupt"

  1. #1
    Member
    Join Date
    Jan 2018
    Location
    Livermore
    Posts
    26

    questionS about "how to disable a particular interrupt"

    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!

  2. #2
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,071
    I think you could use an IntervalTimer and then NVIC_DISABLE_IRQ(my_timer);

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,081
    The disable seems the right thing.

    Indeed __STREXW is safe for READ. Any write could be interrupted and repeated partway though.

  4. #4
    Member
    Join Date
    Jan 2018
    Location
    Livermore
    Posts
    26
    Thanks!! Will try "IntervalTimer" + "NVIC_DISABLE_IRQ" solution.

  5. #5
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,071
    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();

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,564
    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.

  7. #7
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,071
    > 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 by jonr; 10-07-2021 at 07:44 PM.

  8. #8
    Member
    Join Date
    Jan 2018
    Location
    Livermore
    Posts
    26
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •