Keil Logo

RL-ARM: Low Power RTX Applications on Cortex-M Devices


Information in this knowledgebase article applies to:

  • Tick-less RTX operation
  • Cortex-M devices

SYMPTOM

An RTX application configured for low power operation is losing events when:

  • The CPU is in sleep mode, or
  • __WFE() does not put Cortex-M device into low-power sleep mode.

CAUSE

  1. The Event Register is not being set by interrupts on some Cortex-M3 silicon revision prior to r2p1.
  2. The WFE instruction is not available on some Cortex-M implementations so WFI is used to enter deep sleep.

When using Cortex-M low-power mode, RTX tick-less operation is controlled from the idle task.
Typical example:

__task void os_idle_demon (void) {
  uint32_t sleep;

  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;    /* Configure Cortex-M for deep sleep  */
  ...
  /* Configure your system for deep sleep */
  ...

  for (;;) {
    sleep = os_suspend ();              /* OS Suspend                         */

    if (sleep) {
      ...
      /* Setup and enable wakeup timer here */
      ...

      /* Put Cortex-M into deep sleep mode */
      __WFE ();                         /* Wait for event                     */

      /* Adjust actual sleep time (in case of any event) */
      sleep = ...
    }
    os_resume (sleep);                  /* OS Resume                          */
  }
}

Problem arises when an interrupt which interracts with RTX is triggered after os_suspend returned sleep time and before __WFE is called. If WFE instruction is available and is implemented correctly, an exception entry/exit event is latched in the event register, so when WFE is executed, this event is detected, CPU does not enter sleep mode, entire loop is repeated and sleep time recalculated.

In case a.) event register is not set by interrupt and when WFE is executed, core enters sleep mode and waits for next interrupt. Sleep time may be to long since it was not adjusted and as a consequence RTX events may be lost.

In case b.) when WFE is not implemented WFI can be used instead.

WORKAROUND

  • Case a.)

    A software workaround on Cortex-M3 devices prior silicon revision r2p1, is to insert the SEV instruction in all exception handlers which interract with the RTX

    Example:

    void RTC_IRQHandler (void) {
      __SEV();                              /* Exception entry event */
      ...
      /* Process your IRQ here */
      ...
    }
    

    SEV instruction will set event register and interrupt will be registered by WFE instruction, thus WFE will behave as it is fully functional.

  • Case b.)

    Use WFI instruction and implement:

    • a way to avoid __WFI() call, if interrupt which interracts with RTX is triggered
    • an early wake-up mechanism in exception handlers interracting with RTX, with a latency of few instruction cycles

    Example:

    void RTC_IRQHandler (void) {
      ...
      /* IRQ processing */
      ...
    
      if (Suspend) {
        Suspend = __FALSE;                    /* Prevent WFI execution            */
        ...
        /* Ensure early wake-up interrupt here */
        ...
      }
    }
    
    __task void os_idle_demon (void) {
      ...
      /* Configure your system for deep sleep */
      ...
    
      for (;;) {
        Suspend = __TRUE;                          /* Start critical section     */
        sleep = os_suspend();                      /* OS Suspend                 */
    
        if (sleep) {                               /* How long can we sleep?     */
          ...
          /* Setup and enable wakeup timer here */
          ...
    
          if (Suspend) {
            /* If interrupt is expected here, early wake-up mechanism must be    */
            /* implemented, which triggers interrupt after WFI instruction       */
            __WFI();                               /* Enter Power-down mode      */
          }
    
          /* Adjust actual sleep time (in case of any event) */
          sleep = ...
        }
    
        Suspend = __FALSE;
        os_resume(sleep);                          /* OS Resume                  */
      }
    }
    

MORE INFORMATION

  • Cortex-M3 / Cortex-M3 with ETM (AT420/AT425) Errata Notice
  • For more information on tick-less operation, please see Configuration for Low-Power Modes in the CMSIS RTOS usage and description guide

FORUM THREADS

The following Discussion Forum threads may provide information related to this topic.

Last Reviewed: Wednesday, January 25, 2017


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.