Instructions such as IRQ Enable/Disable need to be marked as volatile to prevent obscure 'code motion' issues from the compiler optimizer (turning it off is not the correct solution) moving such instructions to useless locations.
Below is what I use.
Also attached is atomic.h which will show how to save and restore state to answer some of your other questions.
Use it like this:
ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
{
// stuff that needs done with IRQs off
}
State of IRQ restored to on or off as it was before ATOMIC_BLOCK as entered
There are other variations documented in the file.
Think long and hard around recursive interrupts or nested priorities before you use them as well as the needed stack space.
This is for the GCC compiler:
#define ATTR_NO_INSTRUMENT_FUNCTION __attribute__( ( no_instrument_function ) ) /* Really needed for these inlined single instructions */
static inline ATTR_NO_INSTRUMENT_FUNCTION void irq_enable( void )
{
__asm__ __volatile__ ("cpsie i"); /* Clear PRIMASK */
}
/*
* The CPSID instruction is self-synchronized to the instruction
* stream and there is no requirement to insert memory barrier
* instructions after CPSID.
*/
static inline ATTR_NO_INSTRUMENT_FUNCTION void irq_disable( void )
{
__asm__ __volatile__ ("cpsid i");
}