Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs Books & Kits Visualisation Ecosystem Training Contact & Support




Last site update Jan 14 2014

Low Power RTOS For Cortex-M MCUs
Saving power on Cortex-M microcontrollers

[More Advanced]

This page augments the main low power tickless idle page with information that is specific to microcontrollers that use a Cortex-M3 or Cortex-M4F FreeRTOS port.

On this page:


Defining the SysTick frequency when it is not equal to the core frequency

By default, the FreeRTOS Cortex-M port uses the 24-bit SysTick timer to generate tick interrupts.


When SysTick is clocked at the core speed...

Most Cortex-M microcontrollers clock the SysTick timer at the same frequency as the Cortex-M core. When this is the case, the combination of high clock speed and 24-bit resolution result in a sever limitation in the maximum tickless period that can be achieved. To achieve very high power saving gains it is necessary to override the built in tickless idle implementation with an implementation that uses an alternative time source.

If the SysTick timer frequency equals the core frequency then configSYSTICK_CLOCK_HZ must be defined to equal configCPU_CLOCK_HZ in FreeRTOSConfig.h. Alternatively, a definition for configSYSTICK_CLOCK_HZ can just be omitted, in which case it will default to equal configCPU_CLOCK_HZ.


When SysTick is clocked below the core speed...

The maximum tickless period that can be achieved increases dramatically when the frequency of the SysTick timer is less than the frequency of the core.

If the SysTick timer frequency does not equal the core frequency then configSYSTICK_CLOCK_HZ must be defined in FreeRTOSConfig.h to equal the SysTick frequency (in Hz).


Generating a tick interrupt from a clock other than SysTick

Versions of FreeRTOS prior to version 7.3.0 always generate the tick interrupt from the SysTick timer. From FreeRTOS version 7.3.0 it is possible for the application writer to optionally provide their own tick interrupt source. An application writer might want to do this to extend the maximum tickless period that can be achieved, or to generate the tick interrupt from a timer that remains active when the microcontroller is in a deep sleep mode.

To define an alternative timer source:

  1. Setup the timer interrupt

    Define a function to configure a timer to generate a periodic interrupt. The function must have the following name and prototype:

    void vPortSetupTimerInterrupt( void );
    		
    The frequency of the interrupt must equal the value of configTICK_RATE_HZ (which is defined in FreeRTOSConfig.h).

  2. Install the interrupt service routine

    The FreeRTOS tick interrupt handler is called xPortSysTickHandler(). xPortSysTickHandler() must be installed as the handler for the timer that is configured by the application defined vPortSetupTimerInterrupt() function.

  3. Ensure CMSIS names are not being used

    Some FreeRTOS demo applications map the name of the FreeRTOS tick interrupt handler to the default CMSIS SysTick handler name, which is SysTick_Handler(). This is done by including the following line in FreeRTOSConfig.h:

    #define xPortSysTickHandler SysTick_Handler
    		
    This must not be done if the tick interrupt is being generated by a timer other than SysTick.

    Some FreeRTOS packages distributed by third parties have gone further by actually renaming xPortSysTickHandler() to SysTick_Handler() in the FreeRTOS port.c source file. If this is the case then a #define in FreeRTOSConfig.h can be used to reverse the change, as follows:

    #define SysTick_Handler xPortSysTickHandler
    		

    In any case, it is important to ensure the FreeRTOS tick interrupt handler is not installed as the SysTick handler if the SysTick timer is not the interrupt source.


Using Microcontroller Specific Low Power Features

The built in tickless idle implementation uses the WFI (Wait For Interrupt) instruction to suspend execution after stopping the tick interrupt. The following two hook macros are provided to allow application specific power saving code to be inserted either side of the WFI instruction:

  1. configPRE_SLEEP_PROCESSING( xExpectedIdleTime )

    configPRE_SLEEP_PROCESSING() is executed immediately before the WFI instruction. It can be used to turn peripheral clocks off, and activate any microcontroller specific low power functionality.

    The expected idle time in ticks is passed as the only parameter, and can be modified by the macro's implementation. If the implementation sets xExpectedIdleTime to 0 then WFI will not be called. This allows the macro's implementation to override the default sleep mode.

  2. configPOST_SLEEP_PROCESSING( xExpectedIdleTime )

    configPOST_SLEEP_PROCESSING() is executed as soon as the microcontroller leaves its low power state. It can be used to reverse the actions of configPRE_SLEEP_PROCESSING(), and in so doing, return the microcontroller back to its fully operational state.

    The expected idle time in ticks is passed as the only parameter, and can be modified by the macro's implementation. Modifying the expected idle time after the microcontroller has left its low power state should only be attempted by expert users who fully understand the built in Cortex-M low power implementation (by viewing the source code comments).

configPRE_SLEEP_PROCESSING and configPOST_SLEEP_PROCESSING() can be defined in FreeRTOSConfig.h.


Example Configurations

Using the built in tickless idle implementation when SysTick frequency equals core frequency

  1. Set configUSE_TICKLESS_IDLE to 1 in FreeRTOSConfig.h


Using the built in tickless idle implementation when SysTick frequency does not equal the core frequency

  1. Set configUSE_TICKLESS_IDLE to 1 in FreeRTOSConfig.h
  2. Set configSYSTICK_CLOCK_HZ to equal the SysTick clock frequency in Hz.


Using the built in tickless idle implementation when using a clock other than SysTick to generate the tick interrupt

This is not a valid configuration.


Using a clock other than SysTick to generate the tick interrupt

  1. Set configUSE_TICKLESS_IDLE to 2 in FreeRTOSConfig.h.

  2. Provide an implementation of vPortSetupTimerInterrupt() that generates an interrupt at the frequency specified by the configTICK_RATE_HZ FreeRTOSConfig.h constant.

  3. Install xPortSysTickHandler() as the handler for the timer interrupt, and ensure xPortSysTickHandler() is not mapped to SysTick_Handler() in FreeRTOSConfig.h, or renamed as SysTick_Handler() in port.c.

  4. Define portSUPPRESS_TICKS_AND_YIELD() as described on the main tickless idle documentation page.









[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2013 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.