如何测量FreeRTOS 中每个任务的 CPU 使用率?
在 STM32CubeIDE GUI 中启用了所有运行时和任务统计,并进行了相关定义GENERATE_RUN_TIME_STATS、USE_TRACE_FACILITY 和 USE_STATS_FORMATTING_FUNCTIONS。当我调用 vTaskGetRunTimeStats() 时,未返回任何内容。vTaskGetRunTimeStats() 中的函数 uxTaskGetSystemState() 返回任务每次使用 0 个时钟周期。是否需要设置计时器或重新定义某些功能才能正常工作?要启用FreeRTOS的运行时间统计功能,需要在FreeRTOSConfig.h文件中定义以下宏:
#define configGENERATE_RUN_TIME_STATS 1 // 启用运行时间统计功能
#define configUSE_TRACE_FACILITY 1 // 启用可视化追踪调试功能
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 // 启用格式化函数功能
extern volatile uint32_t CPU_RunTime;
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (CPU_RunTime = 0UL)
#define portGET_RUN_TIME_COUNTER_VALUE() CPU_RunTime
上边的两个宏来计算CPU运行时间
为了统计CPU的运行时间,需要使用一个高精度的定时器
我们需要创建一个专门的任务来获取和计算各个任务的CPU使用率
可以使用vTaskList和vTaskGetRunTimeStats函数来获取任务的运行状态和CPU使用情况。
void Cpu_task(void const *argument) {
uint8_t CPU_RunInfo;
while (1) {
memset(CPU_RunInfo, 0, sizeof(CPU_RunInfo));
vTaskList((char *)&CPU_RunInfo);
printf("---------------------------------------------\r
");
printf("任务名 任务状态 优先级 剩余栈 任务序号\r
");
printf("%s", CPU_RunInfo);
printf("---------------------------------------------\r
");
memset(CPU_RunInfo, 0, sizeof(CPU_RunInfo));
vTaskGetRunTimeStats((char *)&CPU_RunInfo);
printf("任务名 运行计数 使用率\r
");
printf("%s", CPU_RunInfo);
printf("---------------------------------------------\r
");
osDelay(200); // 延时500个tick
}
}
由于使用的是32位变量来记录系统运行的时间计数值,按20000Hz的中断频率计算,最大支持计数时间为59.6分钟。超过这个时间后,统计结果将不准确
持续响应定时器的中断可能会对系统性能产生一定影响,特别是在资源有限的嵌入式系统中
FreeRTOS内核没有对总的计数时间做溢出保护,如果需要长时间运行,可能需要考虑其他方法来避免溢出问题。
它容易影响产品的性能,在正式产品中,建议关闭这一功能。
若定时器中断未正确配置或未触发,计时器计数值无法更新,导致统计结果为0 在FreeRTOS中测量每个任务的CPU使用率时,若调用vTaskGetRunTimeStats()未返回有效数据,且uxTaskGetSystemState()显示任务使用0个时钟周期,需重点检查计时器配置和宏定义实现
若定时器中断未正确配置或未触发,计时器计数值无法更新,导致统计结果为0
在用户代码中定义并初始化一个高精度定时器(如TIM6),中断周期建议至少为100μs。
检查中断优先级,确保定时器中断优先级高于FreeRTOS内核中断,避免中断被屏蔽。
在定时器中断服务函数中设置断点,确认中断正常触发。调试时观察g_osRuntimeCounter是否随时间递增。
通过串口输出统计信息,或使用STM32CubeIDE的调试器查看变量值。并且建议启用统计功能会轻微增加系统负载,建议在调试阶段使用,生产环境可关闭。
运行任务后调用vTaskGetRunTimeStats(),检查输出结果是否包含任务名称、运行时间及CPU使用率
芯片出厂时存储的校准值(TS_CAL1、TS_CAL2)是基于特定条件(如3V参考电压、14位ADC)下测得,若实际使用条件(如3.3V参考电压、12位ADC)与之不符,需对校准值进行转换
页:
[1]