一、概念
在 FreeRTOS 中统计任务栈信息和 CPU 占比是为了分析栈使用情况防止溢出、优化性能识别高负载任务、合理分配资源避免内存浪费、调试系统排查阻塞或优先级问题,有助于提升效率、确保稳定性、快速定位问题并防止崩溃,比如在你的蜂鸣器任务中可以确保栈大小足够并检查任务是否因中断占用过多 CPU 来优化调度。
二、先介绍一下什么是钩子函数,因为后面用到的两个函数都要放在钩子函数里面执行。
1. 空闲函数和钩子函数的关系
- 空闲函数(Idle Task):FreeRTOS 自动创建的一个任务,优先级最低(0),在没有其他任务可运行时执行。它的主要作用是执行空闲任务逻辑,例如进入低功耗模式或清理已删除任务的资源。
- 钩子函数(Idle Hook Function):也叫空闲任务钩子,是用户定义的一个函数,FreeRTOS 允许你在空闲任务中调用它。钩子函数不是空闲函数本身,而是空闲任务在每次循环时可以调用的一个用户自定义函数。
回答:空闲函数是不是钩子函数?
- 不是。空闲函数是 FreeRTOS 的空闲任务(vTaskIdle),而钩子函数是用户定义的函数(例如 vApplicationIdleHook),在空闲任务中被调用。
- 钩子函数是空闲任务的一个扩展机制,允许用户在空闲任务运行时插入自定义逻辑。
2. 为什么要把某些操作放在钩子函数中执行?
将操作放在钩子函数(vApplicationIdleHook)中执行有以下原因:
- 利用空闲时间:空闲任务只在没有其他任务可运行时执行,钩子函数可以利用这段时间执行低优先级、非紧急的任务(如统计任务栈信息、CPU 占用率、记录日志、进入低功耗模式),避免影响正常任务的实时性。
- 不干扰调度:钩子函数运行在空闲任务中,优先级最低,不会抢占其他任务,确保系统实时性不受影响。
- 周期性执行:空闲任务会反复运行,钩子函数因此可以周期性地执行某些监控或维护操作(如你之前提到的统计任务栈信息和 CPU 占比)。
- 资源管理:空闲任务负责清理已删除任务的资源(如果启用了 configUSE_IDLE_HOOK),钩子函数可以顺便执行类似的管理任务。
所以:统计任务栈信息和 CPU 占比(例如使用vTaskList(pcWriteBuffer) 或 vTaskGetRunTimeStats)。这些操作适合放在钩子函数中,因为:
- 统计操作不紧急,可以在系统空闲时执行,避免占用关键任务的 CPU 时间。
- 周期性运行钩子函数可以持续监控栈使用和 CPU 占用,及时发现问题(例如栈溢出或任务负载过高)。
三、统计所有任务栈信息(通过串口打印)
一、cubemx配置USE_STATS_FORMATING_FUNCTIONS使能以及USE_IDLE_HOOK使能
二、在钩子函数里调用vTaskList(pcWriteBuffer),串口打印
三、串口结果
四、统计所有任务CPU占比(通过串口打印)
cubemx配置,重新定义getRunTimeCounterValue函数,在钩子函数(上面cubemx以及使能钩子函数了,在freertos.c里面有)执行vTaskGetRunTimeStats
一、cubemx配置GENERATE_RUN_TIME_STATS使能
二、在driver_timer.c中定义getRunTimeCounterValue。
vTaskGetRunTimeStats是通过vTaskSwitchContext(任务切换时统计运行时间)实现得,所以需要完善vTaskSwitchContext函数,而vTaskSwitchContext函数中的getRunTimeCounterValue函数为weak,需要自己定义,于是在driver_timer.c中定义getRunTimeCounterValue。