FreeRTOS Deep Dive · Part 3 of 8

Software Timers & Idle Hook Patterns

FreeRTOS STM32 Intermediate Source Code
FreeRTOS Part 3
FreeRTOS Deep Dive — Part 3
Software Timers & Idle Hook Patterns
29:44
Part 3 / 8
29:44
Intermediate
FreeRTOS v10 · STM32F4
01

Overview

Software timers let you execute a callback after a timeout — without a dedicated task. FreeRTOS manages them in the timer daemon task. This part covers creating one-shot and auto-reload timers, timer daemon priority, and how to use the idle hook for background work.

  • Create one-shot and auto-reload timers with xTimerCreate()
  • Reset, start, and stop timers safely from tasks and ISRs
  • Understand timer daemon priority and why callbacks must be non-blocking
  • Implement vApplicationIdleHook() for CPU usage measurement
02

Timer Types

⏱️
One-Shot
Fires once after the period, then stops automatically. Use for timeouts, debounce, and delayed single actions.
pdFALSE → one-shot
🔄
Auto-Reload
Fires repeatedly on every period. Use for heartbeats, periodic status checks, or polling without a full task.
pdTRUE → auto-reload
🛌
Idle Hook
Called whenever the idle task runs. Perfect for CPU usage counters or entering low-power sleep.
vApplicationIdleHook()
03

Code

01
Heartbeat + watchdog timer
timers.c
C
TimerHandle_t xHeartbeat, xWatchdog;

void vHeartbeatCB(TimerHandle_t t) {
    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);
}

void vWatchdogCB(TimerHandle_t t) {
    uart_puts("[WDG] Sensor timeout
");
    Sensor_Restart();
}

void Timers_Init(void) {
    // Auto-reload: LED blinks every 500ms
    xHeartbeat = xTimerCreate("HB",pdMS_TO_TICKS(500),pdTRUE,0,vHeartbeatCB);
    // One-shot: 5s sensor watchdog
    xWatchdog  = xTimerCreate("WDG",pdMS_TO_TICKS(5000),pdFALSE,0,vWatchdogCB);
    xTimerStart(xHeartbeat, 0);
    xTimerStart(xWatchdog,  0);
}

// Reset watchdog on valid data
void OnSensorData(void) { xTimerReset(xWatchdog, 0); }

// Idle hook — runs when nothing else is ready
void vApplicationIdleHook(void) { idle_cycles++; }
💡
Keep callbacks short and non-blocking
Timer callbacks run inside the daemon task. A long or blocking callback delays all other timers. If you need heavy work, use the callback to send a notification to a dedicated task instead.

Continue the Series

Work through all 8 parts of the FreeRTOS Deep Dive to master real-time embedded systems programming.