This commit is contained in:
J. Nick Koston 2025-05-08 17:20:06 -05:00
parent 57425a765b
commit 4c1111a395
No known key found for this signature in database
2 changed files with 38 additions and 35 deletions

View File

@ -216,9 +216,15 @@ async def to_code(config):
else: else:
add_idf_sdkconfig_option("CONFIG_HEAP_TRACING_SYSTEM", True) add_idf_sdkconfig_option("CONFIG_HEAP_TRACING_SYSTEM", True)
# Enable heap task tracking if requested # Enable runtime stats gathering for task info
if heap_tracing_config[CONF_HEAP_TASK_TRACKING]: if heap_tracing_config[CONF_HEAP_TASK_TRACKING]:
add_idf_sdkconfig_option("CONFIG_HEAP_TASK_TRACKING", True) add_idf_sdkconfig_option(
"CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS", True
)
add_idf_sdkconfig_option(
"CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS", True
)
add_idf_sdkconfig_option("CONFIG_FREERTOS_USE_TRACE_FACILITY", True)
# Generate code to implement heap tracing # Generate code to implement heap tracing
cg.add_global(cg.RawStatement('#include "esp_heap_trace.h"')) cg.add_global(cg.RawStatement('#include "esp_heap_trace.h"'))
@ -231,11 +237,7 @@ async def to_code(config):
) )
) )
# If task tracking is enabled, add the task tracking code # No additional setup needed for task tracking
if heap_tracing_config[CONF_HEAP_TASK_TRACKING]:
max_tasks = heap_tracing_config[CONF_HEAP_TASK_MAX]
# Add the global define to update the max tasks value in the implementation
cg.add_define(f"MAX_HEAP_TASKS {max_tasks}")
# Add helper functions for heap tracing with extern "C" to make them globally accessible # Add helper functions for heap tracing with extern "C" to make them globally accessible
cg.add_global( cg.add_global(

View File

@ -16,46 +16,47 @@
#ifdef USE_API_HEAP_TRACE #ifdef USE_API_HEAP_TRACE
#include "esp_heap_trace.h" #include "esp_heap_trace.h"
#include "esp_heap_task_info.h" #include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
// Forward declare heap tracing functions that will be used in the API class // Forward declare heap tracing functions that will be used in the API class
extern "C" void start_heap_trace(); extern "C" void start_heap_trace();
extern "C" void stop_and_dump_heap_trace(); extern "C" void stop_and_dump_heap_trace();
// Maximum number of tasks we expect to track // Task heap information tracking
#define MAX_HEAP_TASKS 10
// Global storage for task heap info
static heap_task_info_t task_info[MAX_HEAP_TASKS];
static size_t tcb_info_size = 0;
static heap_task_totals_t heap_totals[1] = {{.caps = MALLOC_CAP_DEFAULT}};
// Dump task heap information
extern "C" void dump_task_heap_info() { extern "C" void dump_task_heap_info() {
heap_task_info_params_t heap_info = { // Get basic heap statistics
.task_info = task_info, multi_heap_info_t info;
.size = MAX_HEAP_TASKS, heap_caps_get_info(&info, MALLOC_CAP_INTERNAL);
.totals = heap_totals,
.totals_size = 1,
};
esp_err_t err = heap_caps_get_per_task_info(&heap_info, &tcb_info_size); ESP_LOGI("HEAP", "=== Task Heap Information ===");
if (err != ESP_OK) {
ESP_LOGE("HEAP", "Failed to get per-task heap info: %d", err);
return;
}
ESP_LOGI("HEAP", "Task Heap Information (%d tasks):", tcb_info_size);
ESP_LOGI("HEAP", "-------------------------------------"); ESP_LOGI("HEAP", "-------------------------------------");
ESP_LOGI("HEAP", "%-20s %10s", "Task", "Heap Usage"); ESP_LOGI("HEAP", "Total free bytes: %u", info.total_free_bytes);
ESP_LOGI("HEAP", "Total allocated bytes: %u", info.total_allocated_bytes);
ESP_LOGI("HEAP", "Minimum free bytes: %u", info.minimum_free_bytes);
ESP_LOGI("HEAP", "Largest free block: %u", info.largest_free_block);
ESP_LOGI("HEAP", "Free blocks: %u", info.free_blocks);
ESP_LOGI("HEAP", "Allocated blocks: %u", info.allocated_blocks);
ESP_LOGI("HEAP", "Total blocks: %u", info.total_blocks);
ESP_LOGI("HEAP", "-------------------------------------"); ESP_LOGI("HEAP", "-------------------------------------");
for (size_t i = 0; i < tcb_info_size; i++) { // Get information about running tasks
ESP_LOGI("HEAP", "%-20s %10d bytes", task_info[i].task_name, task_info[i].caps[0]); char buffer[128];
} vTaskList(buffer);
ESP_LOGI("HEAP", "Task Information:");
ESP_LOGI("HEAP", "Name State Priority Stack Num");
ESP_LOGI("HEAP", "-------------------------------------"); ESP_LOGI("HEAP", "-------------------------------------");
ESP_LOGI("HEAP", "Total heap allocated: %d bytes", heap_totals[0].size); ESP_LOGI("HEAP", "%s", buffer);
ESP_LOGI("HEAP", "-------------------------------------");
// Additional runtime statistics about tasks
vTaskGetRunTimeStats(buffer);
ESP_LOGI("HEAP", "Task Runtime Statistics:");
ESP_LOGI("HEAP", "Name Time Percentage");
ESP_LOGI("HEAP", "-------------------------------------");
ESP_LOGI("HEAP", "%s", buffer);
ESP_LOGI("HEAP", "-------------------------------------"); ESP_LOGI("HEAP", "-------------------------------------");
} }
#endif #endif