一种计算 CPU 使用率的方法及其实现原理
1 前言出于性能方面的考虑,有的时候,我们希望知道 CPU 的使用率为多少, 进而判断此 CPU 的负载情况和对于当前运行环境是
否足够“ 胜任” 。本文将介绍一种计算 CPU 占有率的方法以及其实现原理。
2 移植算法
2.1 算法简介
此算法是基于操作系统的, 理论上不限于任何操作系统,只要有任务调度就可以。 本文将以 FreeRTOST 为例来介绍本算法的
使用方法。
本文所介绍的算法出处为随 Cube 库一起提供的, 它在 cube 库中的位置如下图所示:
本文将以 STM32F4 为例, 测试环境为 STM3240G-EVAL 评估板。
2.2 开始移植
本文以 CubeF4 内的示例代码工程
STM32Cube_FW_F4_V1.10.0\Projects\STM324xG_EVAL\Applications\FreeRTOS\FreeRTOS_ThreadCreation 为例, IDE
使用 IAR。
第一步: 使用 IAR 打开 FreeRTOS_ThreadCreation 工程, 将 cpu_utils.c 文件添加到工程, 并在工程中添加对应头文件目录:
第二步: 打开 FreeRTOST 的配置头文件 FreeRTOSConfig.h 修改宏 configUSE_IDLE_HOOK 和 configUSE_TICK_HOOK
的值为 1:
第三步: 继续在 FreeRTOSConfig.h 头文件的末尾处添加 traceTASK_SWITCHED_IN 与 traceTASK_SWITCHED_OUT 定义:
第四步: 在 main.h 头文件中 include “”cmsis_os.h“”
Main.h :
第五步: 修改工程属性, 使编译过程不需要函数原型:
第六步:在工程中任何用户代码处都可以调用 osGetCPUUsage()函数来获取当前 CPU 的使用率:
第七步: 编译并运行测试
在调试状态下使用 Live Watch 窗口监控全部变量 osCPU_Usage 的值:
osCPU_Usage 是在 cpu_utils.c 文件中定义的全局变量,表示当前 CPU 的使用率,是个动态值, 由上图可以, CPU 使用率的
动态值为 20%。 实际在代码中是按第六步中调用 osGetCPUUsage()函数来获取当前 CPU 的使用率的。
至此,算法使用方法介绍完毕。
3 算法实现原理分析
操作系统运行时是不断在不同的任务间进行切换, 而驱动这一调度过程是通过系统 tick 来驱动的,即每产生一次系统 tick 则检
查一下当前正在运行的任务的环境判断是否需要切换任务,即调度, 如果需要,则触发 PendSV,通过在 PendSV 中断调用
vTaskSwitchContext()函数来实现任务的调度。 而本文所要讲述的 CPU 使用率算法是通过在一定时间内( 1000 个时间片内) ,
计算空闲任务所占用的时间片总量, 100 减去空闲任务所占百分比则为工作任务所占百分比,即 CPU 使用率。
此函数为空闲任务钩子函数, 每次当切换到空闲任务时就会运行此钩子函数, 它的作用就是记录当前空闲任务的句柄并保存
到全局变量 xIdleHandle。
此函数为操作系统的 tick 钩子函数,即每次产生系统 tick 中断都会进入到此钩子函数。 此钩子函数实际上就是具体计算 CPU
使用率的算法了。 osCPU_TotalIdleTime 是一个全局变量, 表示在 1000 个 tick 时间内空闲任务总共占用的时间片,
CALCULATION_PERIOD 宏的值为 1000, 即每 1000 个 tick 时间内重新计算一次 CPU 的使用率。
下面两个函数就是如何计算 osCPU_TotalIdleTime 的:
void StartIdleMonitor (void)
{
if( xTaskGetCurrentTaskHandle() == xIdleHandle ) //如果是切入到空闲任务
{
osCPU_IdleStartTime = xTaskGetTickCountFromISR();//记录切入到空闲任务的时间点
}
}
void EndIdleMonitor (void)
{
if( xTaskGetCurrentTaskHandle() == xIdleHandle ) //如果是从空闲任务切出
{
/* Store the handle to the idle task. */
osCPU_IdleSpentTime = xTaskGetTickCountFromISR() - osCPU_IdleStartTime; //计算此次空闲
任务花费多长时间
osCPU_TotalIdleTime += osCPU_IdleSpentTime; //空闲任务所占时间进行累加
}
}这两个函数是调度器钩子函数,在调度器进行任务切进和切出时分别回调, StartIdleMonitor()函数记录切换到空闲任务时的时
间点, EndIdleMonitor()则在推出空闲任务时计算此次空闲任务花费多长时间,并累加到 osCPU_TotalIdleTime, 即空闲任务
总共占用的时间片 。
uint16_t osGetCPUUsage (void)
{
return (uint16_t)osCPU_Usage; //直接返回全局变量 osCPU_Usage, 即 CPU 使用率
}全局变量 osCPU_Usage 保存的就是 CPU 的使用率,它是在操作系统的 tick 钩子函数中每隔 1000 个 tick 就被重新计算一次。
4 结论
通过此方法可以很好的用来评估 STM23 MCU 的运行性能。 mark
学习了,回头试试。 步骤很详细,研究研究 这个非常实用啊 考虑的非常周全啊 和实际的相符吗 这个函数是自己写的还是库函数啊 非常简便的方法 如果占用率很大 就跑不起来吧 有机会试试 Mark! 得到的数据准确吗
一种了解状态变化的简单方法
多次检查也会给单片机带来负荷,对功耗不利
在掌握对象的变化频度时是有效的
占用率很大 就跑不起来的吧
页:
[1]