PaulStoffregen / cores

Teensy Core Libraries for Arduino
507 stars 372 forks source link

Add __irq_enabled() function #633

Open mbenkmann opened 2 years ago

mbenkmann commented 2 years ago

It is better for a function to not simply disable and enable interrupts, so the following pattern is generally better:

int enabled = __irq_enabled();
__disable_irq();
...
if (enabled) __enable_irq();

To be able to use this pattern, a function __irq_enabled() is necessary. The following can be inserted right into the relevant headers (kinetis.h for Teensy 3, imxrt.h for Teensy 4) next to __enable_irq() and disable_irq():

static inline int __irq_enabled() __attribute__((always_inline, unused));
static inline int __irq_enabled()
{
    uint32_t pm;
    __asm__ volatile("MRS %0,PRIMASK" : "=r"(pm)::);
    return (pm & 1) == 0;
};
FrankBoesing commented 2 years ago

Why not return a bool?

mbenkmann commented 2 years ago

@FrankBoesing I don't know what C standard is supposed to be supported.

FrankBoesing commented 2 years ago

gnu++14 (C++ 14)

ssilverman commented 1 year ago

The "atomic" macros can help here, from <util/atomic.h>. They disable/enable interrupts, optionally with saving state. The syntax looks like:

ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  // Do stuff
}

This form guarantees the interrupts get reenabled appropriately.