Index
Effective debugging in ESP-IDF, especially when working with FreeRTOS, involves several techniques and tools. Here’s an overview of useful debugging methods for FreeRTOS applications on ESP32:
- Serial Output: Using
ESP_LOGx()
for console output to log messages, errors, and variable states. - FreeRTOS CLI Commands: Executing commands to check task statuses, heap memory, and other runtime diagnostics.
- ESP-IDF Debugging Tools: Utilizing built-in tools like
idf.py monitor
,openOCD
for hardware debugging, and viewing FreeRTOS task details.
Example: Debugging Techniques in a FreeRTOS Task-Based Application
Here’s a simple application using an LED blink task with debugging features enabled. We’ll include logs, FreeRTOS CLI commands, and a memory check to demonstrate each debugging method.
Setup
Ensure the ESP32 is connected to a serial monitor, and you have the idf.py monitor
tool ready for viewing logs.
Code Example
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_system.h"
// GPIO for LED
#define LED_GPIO GPIO_NUM_2
// Tag for logging
static const char *TAG = "DEBUG_APP";
// Task to blink an LED
void blink_task(void *pvParameter) {
gpio_pad_select_gpio(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
int level = 0;
while (1) {
level = !level;
gpio_set_level(LED_GPIO, level);
ESP_LOGI(TAG, "LED Blink Task: GPIO level %d", level); // Log current LED state
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
// Task to monitor FreeRTOS stats and heap memory
void monitor_task(void *pvParameter) {
while (1) {
// FreeRTOS Task Statistics
ESP_LOGI(TAG, "------------------Task Stats------------------");
ESP_LOGI(TAG, "Task Name Runtime Count Stack Free");
ESP_LOGI(TAG, "---------------------------------------------");
// Print task status info
vTaskList(NULL); // NULL because the task output is going to UART
// Heap memory
size_t free_heap = esp_get_free_heap_size();
ESP_LOGI(TAG, "Free heap memory: %d bytes", free_heap);
vTaskDelay(pdMS_TO_TICKS(5000)); // Delay between stats output
}
}
void app_main(void) {
// Create tasks with priorities
xTaskCreate(blink_task, "Blink Task", 1024, NULL, 5, NULL);
xTaskCreate(monitor_task, "Monitor Task", 2048, NULL, 5, NULL);
}
Explanation
- Serial Output Logging:
- ESP Logging:
ESP_LOGI(TAG, "message")
logs important information, such as the LED state and memory usage. This makes it easy to track the application’s status throughidf.py monitor
or a serial monitor. - Error Logging: Replace
ESP_LOGI()
withESP_LOGE()
for error-level logging if something goes wrong. You can also useESP_LOGD()
for detailed debugging messages.
- ESP Logging:
- FreeRTOS CLI Commands:
- Task Statistics:
vTaskList()
provides a snapshot of all tasks, showing their name, state, stack high watermark (free stack memory), and other useful metrics. - Heap Monitoring: The
monitor_task
logs the available heap memory usingesp_get_free_heap_size()
. This helps in detecting memory leaks over time. - Task Stack Usage: You can check each task’s stack usage to ensure no overflow occurs by examining the “Stack Free” column from
vTaskList()
.
- Task Statistics:
- ESP-IDF Debugging Tools:
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
ESP_LOGx()
outputs, and you can use it to detect issues in real-time. - GDB/OpenOCD Debugging: For more complex issues, especially ones requiring in-depth investigation, use GDB to set breakpoints, step through code, and inspect variable values.
- FreeRTOS Task Management: Use CLI commands available through serial for debugging, such as checking for CPU usage and ensuring no tasks are starving.
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
Example Output on Serial Monitor
Explanation
- Serial Output Logging:
- ESP Logging:
ESP_LOGI(TAG, "message")
logs important information, such as the LED state and memory usage. This makes it easy to track the application’s status throughidf.py monitor
or a serial monitor. - Error Logging: Replace
ESP_LOGI()
withESP_LOGE()
for error-level logging if something goes wrong. You can also useESP_LOGD()
for detailed debugging messages.
- ESP Logging:
- FreeRTOS CLI Commands:
- Task Statistics:
vTaskList()
provides a snapshot of all tasks, showing their name, state, stack high watermark (free stack memory), and other useful metrics. - Heap Monitoring: The
monitor_task
logs the available heap memory usingesp_get_free_heap_size()
. This helps in detecting memory leaks over time. - Task Stack Usage: You can check each task’s stack usage to ensure no overflow occurs by examining the “Stack Free” column from
vTaskList()
.
- Task Statistics:
- ESP-IDF Debugging Tools:
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
ESP_LOGx()
outputs, and you can use it to detect issues in real-time. - GDB/OpenOCD Debugging: For more complex issues, especially ones requiring in-depth investigation, use GDB to set breakpoints, step through code, and inspect variable values.
- FreeRTOS Task Management: Use CLI commands available through serial for debugging, such as checking for CPU usage and ensuring no tasks are starving.
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
Example Output on Serial Monitor
Explanation
- Serial Output Logging:
- ESP Logging:
ESP_LOGI(TAG, "message")
logs important information, such as the LED state and memory usage. This makes it easy to track the application’s status throughidf.py monitor
or a serial monitor. - Error Logging: Replace
ESP_LOGI()
withESP_LOGE()
for error-level logging if something goes wrong. You can also useESP_LOGD()
for detailed debugging messages.
- ESP Logging:
- FreeRTOS CLI Commands:
- Task Statistics:
vTaskList()
provides a snapshot of all tasks, showing their name, state, stack high watermark (free stack memory), and other useful metrics. - Heap Monitoring: The
monitor_task
logs the available heap memory usingesp_get_free_heap_size()
. This helps in detecting memory leaks over time. - Task Stack Usage: You can check each task’s stack usage to ensure no overflow occurs by examining the “Stack Free” column from
vTaskList()
.
- Task Statistics:
- ESP-IDF Debugging Tools:
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
ESP_LOGx()
outputs, and you can use it to detect issues in real-time. - GDB/OpenOCD Debugging: For more complex issues, especially ones requiring in-depth investigation, use GDB to set breakpoints, step through code, and inspect variable values.
- FreeRTOS Task Management: Use CLI commands available through serial for debugging, such as checking for CPU usage and ensuring no tasks are starving.
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
Example Output on Serial Monitor
The output below shows typical information logged from the blink_task
and monitor_task
:
The output below shows typical information logged from the blink_task
and monitor_task
:
Explanation
- Serial Output Logging:
- ESP Logging:
ESP_LOGI(TAG, "message")
logs important information, such as the LED state and memory usage. This makes it easy to track the application’s status throughidf.py monitor
or a serial monitor. - Error Logging: Replace
ESP_LOGI()
withESP_LOGE()
for error-level logging if something goes wrong. You can also useESP_LOGD()
for detailed debugging messages.
- ESP Logging:
- FreeRTOS CLI Commands:
- Task Statistics:
vTaskList()
provides a snapshot of all tasks, showing their name, state, stack high watermark (free stack memory), and other useful metrics. - Heap Monitoring: The
monitor_task
logs the available heap memory usingesp_get_free_heap_size()
. This helps in detecting memory leaks over time. - Task Stack Usage: You can check each task’s stack usage to ensure no overflow occurs by examining the “Stack Free” column from
vTaskList()
.
- Task Statistics:
- ESP-IDF Debugging Tools:
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
ESP_LOGx()
outputs, and you can use it to detect issues in real-time. - GDB/OpenOCD Debugging: For more complex issues, especially ones requiring in-depth investigation, use GDB to set breakpoints, step through code, and inspect variable values.
- FreeRTOS Task Management: Use CLI commands available through serial for debugging, such as checking for CPU usage and ensuring no tasks are starving.
- idf.py monitor: Run this command to view real-time log output from the ESP32. This lets you see all
Example Output on Serial Monitor
The output below shows typical information logged from the blink_task
and monitor_task
:
The output below shows typical information logged from the blink_task
and monitor_task
:
I (1000) DEBUG_APP: LED Blink Task: GPIO level 1
I (2000) DEBUG_APP: LED Blink Task: GPIO level 0
I (5000) DEBUG_APP: ------------------Task Stats------------------
I (5000) DEBUG_APP: Task Name Runtime Count Stack Free
I (5000) DEBUG_APP: ---------------------------------------------
I (5000) DEBUG_APP: Blink Task 10ms 512
I (5000) DEBUG_APP: Monitor Task 10ms 1024
I (5000) DEBUG_APP: IDLE Task 10ms 2048
I (5000) DEBUG_APP: Free heap memory: 40000 bytes
This output demonstrates the use of various debugging techniques:
- Logging Messages: Shows LED task status and GPIO levels, giving insight into task execution.
- Task Statistics: Provides task runtime and stack usage information to detect potential issues with task starvation or stack overflow.
- Heap Memory Monitoring: Tracks available memory over time to detect memory leaks or unexpected consumption.
Summary of Debugging Techniques
- Serial Output Logging: Use
ESP_LOGx()
for logging task states, errors, and values of key variables to detect issues and performance bottlenecks. - FreeRTOS CLI Commands: Monitor task states, stack usage, and system health. Commands like
vTaskList()
and memory functions help track the runtime state of tasks and heap usage. - ESP-IDF Debugging Tools: Use
idf.py monitor
for real-time serial logs and, when necessary, set breakpoints with GDB to dive into specific parts of code for more detailed debugging.
By combining these methods, you can gain deeper insights into application performance and troubleshoot issues effectively in ESP32 applications using FreeRTOS and ESP-IDF.