This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex-M4: guaranteed wakeup from WFI?

Note: This was originally posted on 8th August 2013 at http://forums.arm.com

Hi all!

I'm wondering how to ensure that the Cortex-M4 is always woken up on an interrupt from the WFI instruction when executing code like this:

__disable_irq();
// do something ...
__enable_irq();
__WFI();

If an interrupt is triggered between __enable_irq() and __WFI(), the interrupt handler is processed [font="Arial"]immediately and completed before [/font][font="Courier New"]__WFI() is executed, i.e., [/font][font="Arial"][font="Courier New"]__WFI()[/font] will wait for the next interrupt such that the first one is effectively lost. The ATmega* processors have a very simple solution to this problem: enabling interrupts is always delayed by one clock cycle such that the processor can safely enter sleep mode before interrupts can occur and wake up the processor. Thereby it is guaranteed that the processor is always woken up on an interrupt. How is this done on the Cortex-M4? As far as I know, there is no such enable interrupt delay, or is there a totally different mechanism to ensure wakeup on interrupts?

Thanks & kind regards,
Markus


P.S.: A lengthy discussion on a similar topic is here, though in German language.
[/font]
Parents
  • Note: This was originally posted on 9th August 2013 at http://forums.arm.com


    Could you use WFE instead of WFI?  WFE (Wake for Event) will cause the processor to wake on arrival of an interrupt (if they aren't masked) or an Event.  Where an Event can be generated by executing SEV.

    If you put a SEV instruction into your interrupt handler you'd know that the event register was set, meaning the next WFE instruction would "fail".  As long as you have the WFE in a loop (re-checking the sleep condition on waking) this shouldn't be a problem.


    Good point! The manual says about WFE that if the event register is set:

    "The processor clears the register to 0 and continues executing instructions without entering sleep mode."

    Since WFE is a single instruction, I assume that testing the condition and clearing the flag is an atomic operation, i.e., no code (including interrupt handlers) can be executed after testing the condition and before clearing the flag, right? If this is true, I guess the problem is solved.

    This should probably be used together with SEVONPEND=1 since otherwise a forgotten SEV might lead to a race condition as noted above.

    Thanks & kind regards,
    Markus
Reply
  • Note: This was originally posted on 9th August 2013 at http://forums.arm.com


    Could you use WFE instead of WFI?  WFE (Wake for Event) will cause the processor to wake on arrival of an interrupt (if they aren't masked) or an Event.  Where an Event can be generated by executing SEV.

    If you put a SEV instruction into your interrupt handler you'd know that the event register was set, meaning the next WFE instruction would "fail".  As long as you have the WFE in a loop (re-checking the sleep condition on waking) this shouldn't be a problem.


    Good point! The manual says about WFE that if the event register is set:

    "The processor clears the register to 0 and continues executing instructions without entering sleep mode."

    Since WFE is a single instruction, I assume that testing the condition and clearing the flag is an atomic operation, i.e., no code (including interrupt handlers) can be executed after testing the condition and before clearing the flag, right? If this is true, I guess the problem is solved.

    This should probably be used together with SEVONPEND=1 since otherwise a forgotten SEV might lead to a race condition as noted above.

    Thanks & kind regards,
    Markus
Children
No data