
Battery-operated embedded systems face constant pressure to maximize operational lifetime between charges. One often-overlooked optimization lies in the FreeRTOS tick rate configuration, which directly influences how frequently the microcontroller wakes from low-power states to execute the scheduler. This article examines the relationship between tick rate and power consumption, provides a methodology for selecting an optimal tick rate, details the necessary configuration changes, and quantifies the potential power savings for typical battery-powered applications.
The FreeRTOS kernel relies on a periodic timer interrupt, known as the tick interrupt, to manage timekeeping and task scheduling. By default, this interrupt occurs at a frequency defined by configTICK_RATE_HZ in FreeRTOSConfig.h. Common values range from 100Hz (10ms interval) to 1000Hz (1ms interval), with 1000Hz being frequent in many template projects.
Each tick interrupt serves several critical functions:
vTaskDelay() or semaphore takesHowever, every tick interrupt forces the CPU to exit sleep states, execute the interrupt service routine (ISR), and often run the scheduler before potentially returning to sleep. This wake-up cycle consumes measurable energy each time, particularly significant in battery-operated devices that spend most of their time in idle or sleep modes.
![ASCII diagram showing CPU wake cycles due to tick interrupts]
+----------------+ +----------------+ +----------------+| ASLEEP |--> | TICK ISR |--> | ASLEEP || (Low Power) | | (CPU Awake) | | (Low Power) |+----------------+ +----------------+ +----------------+^ 10ms interval ^ 10ms interval ^ 10ms interval| | |Tick #1 Tick #2 Tick #3
At 1000Hz tick rate, this wake-sleep cycle repeats 1000 times per second. Even if each wake cycle consumes only 10µJ, the tick-related overhead amounts to 10mJ/s or 10mW of continuous power drain. In a device targeting 10µA average current at 3.3V (33µW), this represents a 300x increase in power consumption—clearly unacceptable for battery longevity.
Consider a typical battery-powered sensor node that wakes once per second to take a measurement, transmit data, then return to sleep. The application requires no timing precision finer than 10ms for its operation. Yet if configured with the default 1000Hz tick rate, the CPU experiences 1000 wake-ups per second solely for tick processing, despite having no actual work to do 99% of the time.
This scenario illustrates the core problem: the tick rate often exceeds the application’s actual timing requirements, creating unnecessary power waste without providing functional benefit.
The root cause typically stems from two factors:
To determine whether your tick rate is excessive, ask:
For many applications—periodic sensor readings, user interface updates, communication polling, or control loops with 100ms+ periods—the answer is no. These systems can often operate correctly with tick rates of 100Hz or even lower.
Reducing the FreeRTOS tick rate involves a four-step process:
Begin by identifying all time-dependent operations in your firmware:
vTaskDelay())Record the shortest interval required across all these operations. For example:
In this case, the shortest genuine requirement is 20ms (for debouncing), suggesting a minimum tick rate of 50Hz (1/0.020 = 50Hz) to maintain 20ms resolution.
Choose a tick rate that provides adequate resolution for your shortest requirement while allowing margin for error. A common approach is to select the next standard rate above your calculated minimum:
Standard tick rates to consider: 50Hz, 100Hz, 200Hz, 250Hz, 500Hz, 1000Hz.
Modify FreeRTOSConfig.h with two critical changes:
/* Reduce tick rate to 100Hz (10ms ticks) */#define configTICK_RATE_HZ ( ( TickType_t ) 100 )/* Enable tickless idle to suppress ticks during idle periods */#define configUSE_TICKLESS_IDLE 1
The configUSE_TICKLESS_IDLE setting allows FreeRTOS to enter tickless idle mode when no tasks are ready to run and no timeouts are pending. In this state, the RTOS can suppress tick interrupts entirely for extended periods, waking only when:
This combination—reduced base tick rate plus tickless idle—yields multiplicative power savings compared to simply lowering the tick rate alone.
All timeout values specified in ticks must be adjusted proportionally when changing configTICK_RATE_HZ. For example:
vTaskDelay(1000 / portTICK_PERIOD_MS) for 1-second delayportTICK_PERIOD_MS = 1, so delay = 1000 ticksportTICK_PERIOD_MS = 10, so same delay requires 100 ticksBetter practice is to use the pdMS_TO_TICKS() macro, which automatically adapts to the current tick rate:
vTaskDelay(pdMS_TO_TICKS(1000)); // 1-second delay at any tick rate
After configuration changes, validate that:
To illustrate the impact, consider a typical 32-bit microcontroller running at 3.3V with the following characteristics:
At 1000Hz tick rate:
At 100Hz tick rate with tickless idle:
Power reduction: ~83% from tick-related overhead alone.
In systems with deeper sleep modes or longer idle periods, savings can exceed 90% of the tick-related power component. For a device targeting 10µA average current, reducing tick-related wake-ups might extend battery life by weeks or months depending on battery capacity and duty cycle.
Here’s a concrete example using an STM32L4 microcontroller running FreeRTOS:
#define configTICK_RATE_HZ ( ( TickType_t ) 100 )#define configUSE_TICKLESS_IDLE 1#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
Ensure low-power modes are correctly configured in STM32CubeMX or HAL:
vPortSuppressTicksAndSleep() is called during idleUse an oscilloscope or current probe to measure:
Quick Links
Legal Stuff





