Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


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

[More Advanced]
[See also Tickless Demos on SAM4L, RX100, and STM32L MCUs ]

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

On this page:


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

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


When SysTick is clocked at the core speed...

Most ARM Cortex-M microcontrollers clock the SysTick timer at the same frequency as the ARM 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, and actually replace the WFI with an application specific alternative 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. It is dangerous to set xExpectedIdleTime to any value other than zero!

  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 ARM 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 ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner