主要参考资料:
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);
}