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 任务运行时 最小剩余堆栈大小(栈顶最接近溢出的状态)
相关推荐
梦可尤曦4 天前
Freertos卡在while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
stm32·嵌入式硬件·cubemx·freertos
集大周杰伦5 天前
FreeRTOS 源码结构解析与 STM32 HAL 库移植实践(任务创建、删除篇)
stm32·freertos·实时操作系统·嵌入式开发·rtos·任务调度·任务控制块
BW.SU10 天前
51单片机制作彩屏触摸小电子琴STC32G12K128+RA6809+彩屏1024x600
单片机·嵌入式硬件·51单片机·freertos·stc32g12k128
Zevalin爱灰灰1 个月前
FreeRTOS从入门到精通 第十三章(信号量)
stm32·单片机·嵌入式硬件·操作系统·freertos
Zevalin爱灰灰1 个月前
FreeRTOS从入门到精通 第十二章(FreeRTOS消息队列)
stm32·单片机·嵌入式硬件·操作系统·freertos
黄金右肾1 个月前
STM32之FreeRTOS开发介绍(十九)
stm32·单片机·freertos
小猪写代码2 个月前
STM32 FreeRTOS 基础知识
stm32·单片机·实时操作系统
CV金科2 个月前
freertos的基础(二)内存管理:堆和栈
stm32·开源·arm·freertos·risc-v
国产化创客2 个月前
RK3399开发板Linux实时性改造
linux·物联网·嵌入式·实时操作系统