feat: Add PROFILE command — heap, stack watermarks, CPU runtime stats
- PROFILE command returns heap usage (free/min/dram/iram), per-task stack high watermark, and per-task CPU % (when CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is enabled) - Enable FreeRTOS runtime stats in sdkconfig.defaults - Enlarge cmd reply buffer to 1400 bytes for multi-line output - Add esp_heap_caps.h include
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
#include "esp_now.h"
|
#include "esp_now.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
#include "esp_ota_ops.h"
|
#include "esp_ota_ops.h"
|
||||||
#include "esp_https_ota.h"
|
#include "esp_https_ota.h"
|
||||||
#include "esp_http_client.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);
|
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 <url> */
|
/* OTA <url> */
|
||||||
if (strncmp(cmd, "OTA ", 4) == 0) {
|
if (strncmp(cmd, "OTA ", 4) == 0) {
|
||||||
const char *url = cmd + 4;
|
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);
|
ESP_LOGI(TAG, "Command listener on UDP port %d", CONFIG_CSI_CMD_PORT);
|
||||||
|
|
||||||
char rx_buf[128];
|
char rx_buf[128];
|
||||||
char reply_buf[256];
|
char reply_buf[1400];
|
||||||
struct sockaddr_in src_addr;
|
struct sockaddr_in src_addr;
|
||||||
socklen_t src_len;
|
socklen_t src_len;
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
|||||||
# FreeRTOS
|
# FreeRTOS
|
||||||
#
|
#
|
||||||
CONFIG_FREERTOS_HZ=1000
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
|
||||||
|
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP32-specific
|
# ESP32-specific
|
||||||
|
|||||||
Reference in New Issue
Block a user