cancel
Showing results for 
Search instead for 
Did you mean: 

Disabling Interrupts

Carl_G
Senior II

On STM32G0 is it faster to disable and enable interrupts using the functions 

__STATIC_FORCEINLINE void __enable_irq(void)
{
  __ASM volatile ("cpsie i" : : : "memory");
}
__STATIC_FORCEINLINE void __disable_irq(void)
{
  __ASM volatile ("cpsid i" : : : "memory");
}

I'm not sure what "memory" does in the above. 

or is the code below faster

__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
{
  if ((int32_t)(IRQn) >= 0)
  {
    NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
    __DSB();
    __ISB();
  }
}
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
  if ((int32_t)(IRQn) >= 0)
  {
    __COMPILER_BARRIER();
    NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
    __COMPILER_BARRIER();
  }
}

I realize using the NVIC is more fine grained but just wondering what the memory behaviors differences are of these two and if one is heavier than the other.

Thanks!

 

xxx

1 ACCEPTED SOLUTION

Accepted Solutions
ASEHST
ST Employee

Hello,

Thank you for your report.

The functions __enable_irq and __disable_irq are optimized for quickly enabling and disabling all interrupts globally by directly manipulating the PRIMASK register, typically requiring only a few CPU cycles.

In contrast, __NVIC_DisableIRQ and __NVIC_EnableIRQ are designed to enable or disable specific interrupts at the NVIC level, which involves more complex operations such as accessing and modifying NVIC registers.

Therefore, if you need to rapidly enable or disable all interrupts globally, __enable_irq and __disable_irq are the faster options. However, if you need to manage specific interrupts, you will need to use __NVIC_DisableIRQ and __NVIC_EnableIRQ, with the understanding that these functions are slower due to the additional complexity involved.

 

With Regards,

If your question is answered, please close this topic by clicking "Accept as Solution".

View solution in original post

2 REPLIES 2
TDK
Guru

They're not equivalent.

The first disables all interrupts, and will generally be faster.

The second disables a particular interrupt.

If you feel a post has answered your question, please click "Accept as Solution".
ASEHST
ST Employee

Hello,

Thank you for your report.

The functions __enable_irq and __disable_irq are optimized for quickly enabling and disabling all interrupts globally by directly manipulating the PRIMASK register, typically requiring only a few CPU cycles.

In contrast, __NVIC_DisableIRQ and __NVIC_EnableIRQ are designed to enable or disable specific interrupts at the NVIC level, which involves more complex operations such as accessing and modifying NVIC registers.

Therefore, if you need to rapidly enable or disable all interrupts globally, __enable_irq and __disable_irq are the faster options. However, if you need to manage specific interrupts, you will need to use __NVIC_DisableIRQ and __NVIC_EnableIRQ, with the understanding that these functions are slower due to the additional complexity involved.

 

With Regards,

If your question is answered, please close this topic by clicking "Accept as Solution".