This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to use WFE reliably?

After reading the fine-print regarding WFE, I came to the conclusion that WFE can send the CPU to sleep even if interrupts are still pending. Such interrupts would not be able then to wake the CPU. In order to wake the CPU the interrupt has to occur while the CPU is sleeping. Is this correct? In my case I want to wake the CPU with a key press (via the GPIOTE PORT event), so I wonder if sleeping like this

if (!NVIC_GetPendingIRQ(GPIOTE_IRQn))
  __wfe();

would allow the CPU to reliably wake up via the GPIOTE_IRQn interrupt (if GPIOTE_IRQn was not pending and thus the CPU was actually sent to sleep)? In other words, could a GPIOTE_IRQn interrupt occur right after having checked the interrupt pending flag but before or while executing WPE so that the CPU would still fall asleep and not wake up from this interrupt? I know that this would be a very rare case as the time span between NVIC_GetPendingIRQ() and __wpe() is so short, but if it happened it would render my device unresponsive.

Parents
  • Yes your code has a race condition in it, it's possible for the interrupt to arrive between your test and the WFE. Unlikely, but possible.

    Setting SEVONPEND will cause the the event flag to be set every time there's a pending interrupt, and WFE doesn't sleep if the event flag is set. That should do what you want.

    I've found every time I looked into this that, despite the vast amount of documentation ARM writes about WFI and WFE, it's very hard to find definitive answers to questions about exactly, precisely in all instances when the event flag is set .. and the books on Cortex tend to skate over it too.

Reply
  • Yes your code has a race condition in it, it's possible for the interrupt to arrive between your test and the WFE. Unlikely, but possible.

    Setting SEVONPEND will cause the the event flag to be set every time there's a pending interrupt, and WFE doesn't sleep if the event flag is set. That should do what you want.

    I've found every time I looked into this that, despite the vast amount of documentation ARM writes about WFI and WFE, it's very hard to find definitive answers to questions about exactly, precisely in all instances when the event flag is set .. and the books on Cortex tend to skate over it too.

Children
Related