主要参考资料:
CSDN文章《ESP32 IDF开发调试奇技淫巧》: https://blog.csdn.net/qq_43332314/article/details/131859971
目录
- 查询系统剩余堆/最小堆大小
 - 查询线程剩余栈大小
 - 方法一
 - 方法二
 
- 查询CPU占用率
 
查询系统剩余堆/最小堆大小
查询系统剩余堆、最小堆大小的 API 位于 esp_system 组件中。剩余堆大小过小,会导致 malloc 申请内存失败,当剩余堆不够时,很多网络操作均会失败,这是由于网路操作内部涉及很多 malloc 操作。
 (1)查询系统剩余堆大小,返回值为 Byte
uint32_t esp_get_free_heap_size( void );
 
(2)查询系统最小堆大小,返回值为 Byte
uint32_t esp_get_minimun_free_heap_size(void);
 
示例:
while (1) {
    remain_heap = esp_get_free_heap_size() / 1024;
	ESP_LOGW(TAG, "Remaining heap tight:%lu k", remain_heap);
    vTaskDeley(300);
}
 
查询线程剩余栈大小
方法一
由于ESP32 IDF采用FreeRTOS,因此查询线程所使用的栈大小空间,可通过FreeRTOS API实现,函数原型如下:
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
 
返回值为线程栈使用的高水位线,所谓高水位线也即自任务开始运行以来,任务所使用的栈最大时所剩余的栈大小。因此此值越大,代表线程峰值栈剩余量越大。
示例:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void task_function(void *pvParameter) {
    int stack_left = 0;
    
    stack_left = uxTaskGetStackHighWaterMark(NULL);
    printf("Stack left: %d bytes\n", stack_left);
    while (1) {
        char c[1000] = {0};
        stack_left = uxTaskGetStackHighWaterMark(NULL);
        printf("Stack left: %d bytes\n", stack_left);
        vTaskDelay(100);
    }
    
    // 线程结束
    vTaskDelete(NULL);
}
int app_main(void)
{
    xTaskCreate(task_function, "task", 4096, NULL, 1, NULL);
    vTaskDelete(NULL);
}
 
方法二
使用 vTaskList() 查看,函数原型
void vTaskList( char * pcWriteBuffer );
 
使用此函数需先配置 menuconfig 打开部分功能:
idf menuconfig → Component config → FreeRTOS → kernel→Enable FreeRTOS trace facility
 idf menuconfig → Component config → FreeRTOS → kernel→Enable FreeRTOS trace facility → Enable FreeRTOS stats formatting functions
 idf menuconfig → Component config → FreeRTOS → kernel→Enable FreeRTOS trace facility → Enable display of xCoreID in vTaskList
 
 示例:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <string.h>
void task_function(void *pvParameter) {
    uint8_t CPU_RunInfo[400];
 
    while (1) {
        memset(CPU_RunInfo, 0, 400);
        vTaskList((char *)&CPU_RunInfo);
 
        printf("----------------------------------------------------\r\n");
        printf("task_name   status   priority   stack   num   core\r\n");
        printf("%s", CPU_RunInfo);
        printf("----------------------------------------------------\r\n");
 
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}
int app_main(void)
{
    xTaskCreate(task_function, "task", 4096, NULL, 1, NULL);
    vTaskDelete(NULL);
}
 

 第一列,任务名称
 第二列,任务状态
 X: running
 B: blocked
 R: ready
 D: deleted
 S: suspended
 第三列,任务优先级
 数值越大,优先级越高
 第四列,任务栈
 数值越大,代表剩余的任务栈空间越大,单位Byte
 注意此值为当前剩余栈大小,而不是峰值剩余栈大小
 第五列,任务号
 代表任务创建顺序
 第六列,任务内核
查询CPU占用率
esp32 idf查询任务 CPU 占用率,依旧可以通过FreeRTOS的任务统计功能来实现,函数原型如下:
void vTaskGetRunTimeStats( char * pcWriteBuffer );
 
配置menuconfig 打开:
idf.py menuconfig → Component config → FreeRTOS → Kernel → configGENERATE_RUN_TIME_STATS
 
示例:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <string.h>
void task_function(void *pvParameter) {
    uint8_t CPU_RunInfo[400];
    while (1) {
        memset(CPU_RunInfo, 0, 400);
        vTaskGetRunTimeStats((char *)&CPU_RunInfo);
 
        printf("task_name      run_cnt                 usage_rate   \r\n");
        printf("%s", CPU_RunInfo);
        printf("----------------------------------------------------\r\n");
 
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}
int app_main(void)
{
    xTaskCreate(task_function, "task", 4096, NULL, 1, NULL);
    vTaskDelete(NULL);
}
 


















