diff --git a/get-started/csi_recv_router/main/app_main.c b/get-started/csi_recv_router/main/app_main.c index 5d5dffc..e0f1443 100644 --- a/get-started/csi_recv_router/main/app_main.c +++ b/get-started/csi_recv_router/main/app_main.c @@ -31,6 +31,7 @@ #include "esp_now.h" #include "esp_timer.h" #include "esp_task_wdt.h" +#include "esp_heap_caps.h" #include "esp_ota_ops.h" #include "esp_https_ota.h" #include "esp_http_client.h" @@ -848,6 +849,55 @@ static int cmd_handle(const char *cmd, char *reply, size_t reply_size) return strlen(reply); } + /* PROFILE */ + if (strcmp(cmd, "PROFILE") == 0) { + int pos = 0; + /* Heap info */ + size_t free_heap = esp_get_free_heap_size(); + size_t min_heap = esp_get_minimum_free_heap_size(); + size_t free_dram = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t total_dram = heap_caps_get_total_size(MALLOC_CAP_8BIT); + size_t free_iram = heap_caps_get_free_size(MALLOC_CAP_IRAM_8BIT); + pos += snprintf(reply + pos, reply_size - pos, + "OK PROFILE\nHEAP free=%u min=%u dram=%u/%u iram=%u\n", + (unsigned)free_heap, (unsigned)min_heap, + (unsigned)free_dram, (unsigned)total_dram, (unsigned)free_iram); + + /* Per-task stack watermarks */ + pos += snprintf(reply + pos, reply_size - pos, "TASKS\n"); + const char *task_names[] = {"led_task", "cmd_task", "adaptive", "ble_host", "main", NULL}; + for (int i = 0; task_names[i] != NULL && pos < (int)reply_size - 60; i++) { + TaskHandle_t th = xTaskGetHandle(task_names[i]); + if (th) { + UBaseType_t hwm = uxTaskGetStackHighWaterMark(th); + pos += snprintf(reply + pos, reply_size - pos, + " %-12s stack_free=%u\n", task_names[i], (unsigned)(hwm * sizeof(StackType_t))); + } + } + +#if defined(CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS) && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS + /* CPU runtime stats */ + UBaseType_t n = uxTaskGetNumberOfTasks(); + TaskStatus_t *tasks = malloc(n * sizeof(TaskStatus_t)); + if (tasks) { + uint32_t total_time; + n = uxTaskGetSystemState(tasks, n, &total_time); + if (total_time > 0) { + pos += snprintf(reply + pos, reply_size - pos, "CPU\n"); + for (UBaseType_t i = 0; i < n && pos < (int)reply_size - 60; i++) { + uint32_t pct = (tasks[i].ulRunTimeCounter * 100) / total_time; + if (pct > 0 || tasks[i].ulRunTimeCounter > 0) { + pos += snprintf(reply + pos, reply_size - pos, + " %-12s %3lu%%\n", tasks[i].pcTaskName, (unsigned long)pct); + } + } + } + free(tasks); + } +#endif + return pos; + } + /* OTA */ if (strncmp(cmd, "OTA ", 4) == 0) { const char *url = cmd + 4; @@ -899,7 +949,7 @@ static void cmd_task(void *arg) ESP_LOGI(TAG, "Command listener on UDP port %d", CONFIG_CSI_CMD_PORT); char rx_buf[128]; - char reply_buf[256]; + char reply_buf[1400]; struct sockaddr_in src_addr; socklen_t src_len; diff --git a/get-started/csi_recv_router/sdkconfig.defaults b/get-started/csi_recv_router/sdkconfig.defaults index 0098602..eb2f2a2 100644 --- a/get-started/csi_recv_router/sdkconfig.defaults +++ b/get-started/csi_recv_router/sdkconfig.defaults @@ -35,6 +35,8 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y # FreeRTOS # CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y # # ESP32-specific