FreeRTOS Deep Dive · Part 8 of 8
Debugging & Trace with Tracealyzer
50:40
Part 8 / 8
🧠 FreeRTOS Deep Dive Series · 8 Parts
Part 8 of 8
Part 01
Scheduler, Priorities & Context Switch
55:30
Part 02
Task Notifications vs Event Groups
38:15
Part 03
Software Timers & Idle Hook Patterns
29:44
Part 04
Queues, Semaphores & Mutexes
42:18
Part 05
Memory Management & Heap Models
36:50
Part 06
Stack Sizing & Overflow Detection
31:20
Part 07
Low-Power RTOS & Tickless Idle
44:05
Part 08
Debugging & Trace with Tracealyzer
50:40
01
Overview
RTOS bugs are hard to debug with printf — the scheduler hides timing issues that only appear under load. This part covers FreeRTOS's built-in trace facilities, per-task CPU usage with runtime stats, and how to use Tracealyzer to visually identify priority inversion, starvation, and missed deadlines.
- Enable runtime stats to measure per-task CPU usage as a percentage
- Use
vTaskList()to dump all task states and watermarks to UART - Integrate Percepio Tracealyzer for visual timeline debugging
- Identify priority inversion, starvation, and CPU hogs from trace recordings
02
Debug Tools
vTaskList()
Dumps a table of all tasks: name, state, priority, stack watermark, and number. Print over UART from a monitor task.
configUSE_TRACE_FACILITY = 1
Runtime Stats
Measures CPU time consumed per task. Requires a 10–100× faster free-running counter. Shows % CPU per task.
configGENERATE_RUN_TIME_STATS = 1
Tracealyzer
Records timestamped FreeRTOS API events. Visualises task execution, preemptions, and CPU load on a timeline.
Percepio FreeRTOS+Trace
03
Code
01
Runtime stats + vTaskList UART dumpdebug_monitor.c
C
#define configUSE_TRACE_FACILITY 1 #define configGENERATE_RUN_TIME_STATS 1 #define configUSE_STATS_FORMATTING_FUNCS 1 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() TIM2_Init() #define portGET_RUN_TIME_COUNTER_VALUE() TIM2->CNT static char buf[1024]; void vDebugTask(void *pv) { while(1) { uart_puts(" == Tasks == "); vTaskList(buf); uart_puts(buf); uart_puts(" == CPU == "); vTaskGetRunTimeStats(buf); uart_puts(buf); uart_printf(" Free heap: %u ",xPortGetFreeHeapSize()); vTaskDelay(pdMS_TO_TICKS(15000)); } } void TIM2_Init(void) { __HAL_RCC_TIM2_CLK_ENABLE(); TIM2->PSC = (HAL_RCC_GetPCLK1Freq()/1000000UL)-1; TIM2->ARR = 0xFFFFFFFF; TIM2->CR1 = TIM_CR1_CEN; }
Runtime counter must be faster than the tick
Set your timer to run at least 10× the tick frequency. At a 1kHz tick, a 1MHz TIM2 gives microsecond resolution and is a solid default.
Continue the Series
Work through all 8 parts of the FreeRTOS Deep Dive to master real-time embedded systems programming.