FreeRTOS 任务管理与运行时间统计:API 解析与配置实践

1. FreeRTOS 任务相关 API 函数

1.1 FreeRTOS 任务相关 API 函数介绍

FreeRTOS 提供了一系列 API 来管理任务的状态、优先级和运行信息。以下是任务管理相关的主要 API 及其功能说明:

1.1.1 任务优先级管理

API 函数 作用
uxTaskPriorityGet() 获取任务的当前优先级
vTaskPrioritySet() 设置任务的优先级

1.1.2 任务状态和数量查询

API 函数 作用
uxTaskGetNumberOfTasks() 获取当前系统任务的数量
uxTaskGetSystemState() 获取所有任务的状态信息
eTaskGetState() 获取指定任务的状态

1.1.3 任务句柄获取

API 函数 作用
xTaskGetCurrentTaskHandle() 获取当前正在运行任务的任务句柄
xTaskGetHandle() 通过任务名称获取任务的句柄

1.1.4 任务堆栈监测

API 函数 作用
uxTaskGetStackHighWaterMark() 获取任务的堆栈历史最小剩余空间(检测堆栈使用情况)

1.1.5 任务信息获取(分析 CPU 资源分配

API 函数 作用
vTaskGetInfo() 获取指定任务的信息
vTaskList() 以表格形式获取所有任务的信息
vTaskGetRunTimeStats() 获取任务的运行时间(分析 CPU 资源分配
任务时间统计配置需求:

​ 宏configGENERATE_RUN_TIME_STATS、configUSE_STATS_FORMATTING_FUNCTIONS 、configSUPPORT_DYNAMIC_ALLOCATION必须定义为 1,才可使用此函数。此外,应用程序还必须提供portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()和portGET_RUN_TIME_COUNTER_VALUE()的宏定义,分别用于配置外设 定时器/计数器和返回定时器的当前计数值。计数器的频率应该至少是 滴答计数的 10 倍,时间基数越快, 统计数据就越准确------但定时器值也会越早溢出。

注意:此函数在执行期间会禁用中断。它 不是作为正常的应用程序运行时的工具,而是作为调试辅助工具。

​ vTaskGetRunTimeStats() 调用 uxTaskGetSystemState(), 然后将 uxTaskGetSystemState()生成的原始数据转换为 易于阅读的 (ASCII) 表格形式,表格中会显示 每个任务在运行状态下所花费的时间(即每个任务消耗的 CPU 时间量)。数据以 绝对值和百分比值的形式提供。绝对值的分辨率 取决于应用程序提供的运行时间统计时钟的频率。

任务时间统计配置示例:

1 ) FreeRTOSConfig.h文件:

c 复制代码
/* 运行时间和任务状态统计相关定义 */
#define configGENERATE_RUN_TIME_STATS 1 /* 1: 使能任务运行时间统计功能, 默认: 0 */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* 使能统计信息格式化函数 */
#define configSUPPORT_DYNAMIC_ALLOCATION 1 /* 配置动态创建任务 */

#if configGENERATE_RUN_TIME_STATS
extern volatile unsigned long ulHighFrequencyTimerTicks;
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (ulHighFrequencyTimerTicks = 0UL) // 初始化运行时间统计计数器,在FreeRTOS 启动前调用
#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks  //返回当前的运行时间计数值
#endif

2 ) 新开一个定时器中断(100KHz),用于 ulHighFrequencyTimerTicks 变量计数

c 复制代码
// 记得使能定时器中断,
volatile unsigned long ulHighFrequencyTimerTicks;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM3){
        ulHighFrequencyTimerTicks ++;
    }
}

3 ) 获取任务时间统计主程序

c 复制代码
vTaskGetRunTimeStats(taskInfo);
printf("%s\r\n", taskInfo);

4 ) 输出示例:(依次为:任务名 运行时间 占比%)

c 复制代码
task3          	5145		<1%
IDLE           	1316917		99%
task1          	27		    <1%
task2          	27		    <1%

注意 :任务运行时间的定时器中断频率设为高频中断可能会导致 FreeRTOS 任务无法执行。例如:当定时器中断频率设为 1MHz(1微秒触发一次中断)时,CPU 过于频繁进入中断,导致任务调度被阻塞,任务无法执行。而 0.1MHz(10微秒触发一次)时,CPU 有足够时间执行任务,程序正常运行。最佳方案是 使用硬件计数(直接读取 TIMx->CNT)而非高频中断,避免 ISR 过载影响 FreeRTOS 任务调度,同时保持高精度的运行时间统计。

1.1.6 TaskStatus_t 任务状态信息结构体

TaskStatus_t 结构体用于 存储 FreeRTOS 任务的状态信息 ,可以通过 vTaskGetInfo()uxTaskGetSystemState() 获取任务信息。它的各个字段作用如下:

字段名 类型 说明
xHandle TaskHandle_t 任务句柄,标识该任务
pcTaskName const char * 任务名称(xTaskCreate() 指定的名称)
xTaskNumber UBaseType_t 任务的唯一编号
eCurrentState eTaskState 任务当前状态(RunningBlockedSuspended 等)
uxCurrentPriority UBaseType_t 任务当前优先级(可能是继承的)
uxBasePriority UBaseType_t 任务的基础优先级(未继承时的初始优先级)
ulRunTimeCounter configRUN_TIME_COUNTER_TYPE 任务已运行的总时间(configGENERATE_RUN_TIME_STATS 使能时有效)
pxStackBase StackType_t * 任务堆栈的起始地址
pxTopOfStack (可选) StackType_t * (仅在某些配置下) 任务堆栈当前的栈顶地址
pxEndOfStack (可选) StackType_t * (仅在某些配置下) 任务堆栈的最高地址
usStackHighWaterMark configSTACK_DEPTH_TYPE 任务运行时 最小剩余堆栈大小(栈顶最接近溢出的状态)
相关推荐
爱学电子的刻刻帝1 天前
基于FreeRTOS和LVGL的多功能低功耗智能手表
stm32·freertos·lvgl·智能手表
cykaw25902 天前
FreeRTOS任务通知
stm32·单片机·嵌入式·freertos
zhmc2 天前
configMAX_SYSCALL_INTERRUPT_PRIORITY和configKERNEL_INTERRUPT_PRIORITY
freertos
zhmc2 天前
FreeRTOS临界区
freertos
大牛攻城狮3 天前
使用stm32cubeide stm32f407 lan8720a freertos lwip 实现udp client网络数据转串口数据过程详解
stm32·freertos·lwip·stm32cubeide·网络转串口·lan8720a·udp服务端客户端
hongqi102913 天前
刘火良FreeRTOS内核实现与应用学习之6——多优先级
stm32·学习·freertos
hongqi102919 天前
刘火良FreeRTOS内核实现与应用学习之4——空闲任务与阻塞延时
学习·freertos
xtudj20 天前
项目实战:基于瑞萨RA6M5构建多节点OTA升级-创建工程MCUBoot<二>
单片机·mcu·嵌入式·freertos·uboot·mcuboot·瑞萨renesas
Nav.22 天前
从bootloader跳到APP需要几步?
stm32·单片机·freertos
xtudj1 个月前
浅谈分布式多节点嵌入式系统中RS485总线指令冲突解决及性能优化
分布式·嵌入式·freertos·rs485通讯冲突检测·rs485通讯性能优化