[经验] 一种基于FreeRTOS的CPU使用率测算方法及原理介绍
2017-06-11 10:25
316 查看
1、前言
出于性能方面的考虑,有的时候,我们希望知道CPU的使用率为多少,进而判断此CPU的负载情况和对于当前运行环境是否足够“胜任”。本文将介绍一种计算CPU占有率的方法以及其实现原理。
2、移植算法2.1
算法简介
此算法是基于操作系统的,理论上不限于任何操作系统,只要有任务调度就可以。本文将以FreeRTOST为例来介绍本算法的使用方法。
本文所介绍的算法出处为随Cube库一起提供的,它在cube库中的位置如下图所示:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162203ex4t076poxzrqva6.jpg.thumb.jpg)
本文将以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文件添加到工程,并在工程中添加对应头文件目录:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162208uzz71woo1j5axx21.jpg.thumb.jpg)
第二步:打开FreeRTOST的配置头文件FreeRTOSConfig.h修改宏configUSE_IDLE_HOOK和configUSE_TICK_HOOK的值为1:
#defineconfigUSE_PREEMPTION 1
#defineconfigUSE_IDLE_HOOK 1 //修改此宏的值为1
#defineconfigUSE_TICK_HOOK 1 //修改此宏的值为1
#defineconfigCPU_CLOCK_HZ (SystemCoreClock )
#defineconfigTICK_RATE_HZ ( (TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 8 )
#define configMINIMAL_STACK_SIZE (( uint16_t ) 128 )
第三步:继续在FreeRTOSConfig.h头文件的末尾处添加traceTASK_SWITCHED_IN与traceTASK_SWITCHED_OUT定义:
#definetraceTASK_SWITCHED_IN() extern voidStartIdleMonitor(void); \
StartIdleMonitor()
#define traceTASK_SWITCHED_OUT() extern voidEndIdleMonitor(void); \
EndIdleMonitor()
第四步:在main.h头文件中include“”cmsis_os.h“”
Main.h :
#include "stm32f4xx_hal.h"
#include "stm324xg_eval.h"
#include "cmsis_os.h" //添加包含此头文件
//…
第五步:修改工程属性,使编译过程不需要函数原型:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162214wqvrpvqiqv0bpala.jpg.thumb.jpg)
第六步:在工程中任何用户代码处都可以调用osGetCPUUsage()函数来获取当前CPU的使用率:
static void LED_Thread2(void const *argument)
{
uint32_t count;
uint16_t usage =0;
(void) argument;
for(;;)
{
count =osKernelSysTick() + 10000;
/* Toggle LED2 every500 ms for 10 s */
while (count >=osKernelSysTick())
{
BSP_LED_Toggle(LED2);
osDelay(500);
}
usage =osGetCPUUsage(); //获取当前CPU的使用率
/* Turn off LED2 */
BSP_LED_Off(LED2);
/* Resume Thread 1 */
osThreadResume(LEDThread1Handle);
/* Suspend Thread 2 */
osThreadSuspend(NULL);
}
}
第七步:编译并运行测试
在调试状态下使用Live Watch窗口监控全部变量osCPU_Usage的值:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162221u4re2rmsum441ss4.png.thumb.jpg)
osCPU_Usage是在cpu_utils.c文件中定义的全局变量,表示当前CPU的使用率,是个动态值,由上图可以,CPU使用率的动态值为20%。实际在代码中是按第六步中调用osGetCPUUsage()函数来获取当前CPU的使用率的。
至此,算法使用方法介绍完毕。
3 、算法实现原理分析
操作系统运行时是不断在不同的任务间进行切换,而驱动这一调度过程是通过系统tick来驱动的,即每产生一次系统tick则检查一下当前正在运行的任务的环境判断是否需要切换任务,即调度,如果需要,则触发PendSV,通过在PendSV中断调用vTaskSwitchContext()函数来实现任务的调度。而本文所要讲述的CPU使用率算法是通过在一定时间内(1000个时间片内),计算空闲任务所占用的时间片总量,100减去空闲任务所占百分比则为工作任务所占百分比,即CPU使用率。
void vApplicationIdleHook(void)
{
if( xIdleHandle == NULL )
{
/* Store the handle tothe idle task. */
xIdleHandle =xTaskGetCurrentTaskHandle(); //记录空闲任务的句柄
}
}
此函数为空闲任务钩子函数,每次当切换到空闲任务时就会运行此钩子函数,它的作用就是记录当前空闲任务的句柄并保存到全局变量xIdleHandle。
void vApplicationTickHook (void)
{
static int tick = 0;
if(tick ++ >CALCULATION_PERIOD) //每1000个tick,刷新一次CPU使用率
{
tick = 0;
if(osCPU_TotalIdleTime> 1000)
{
osCPU_TotalIdleTime =1000;
}
osCPU_Usage = (100 -(osCPU_TotalIdleTime * 100) / CALCULATION_PERIOD); //这行代码就是CPU使用率的具体计算方法了
osCPU_TotalIdleTime =0;
}
}
此函数为操作系统的tick钩子函数,即每次产生系统tick中断都会进入到此钩子函数。此钩子函数实际上就是具体计算CPU使用率的算法了。osCPU_TotalIdleTime是一个全局变量,表示在1000个tick时间内空闲任务总共占用的时间片,CALCULATION_PERIOD宏的值为1000,即每1000个tick时间内重新计算一次CPU的使用率。
下面两个函数就是如何计算osCPU_TotalIdleTime的:
void StartIdleMonitor(void)
{
if( xTaskGetCurrentTaskHandle() ==xIdleHandle ) //如果是切入到空闲任务
{
osCPU_IdleStartTime =xTaskGetTickCountFromISR();//记录切入到空闲任务的时间点
bd84
}
}
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的运行性能
原文地址:http://bbs.eeworld.com.cn/thread-497511-1-1.html
本文章系转载,如有侵权,请原作者联系,删除。
出于性能方面的考虑,有的时候,我们希望知道CPU的使用率为多少,进而判断此CPU的负载情况和对于当前运行环境是否足够“胜任”。本文将介绍一种计算CPU占有率的方法以及其实现原理。
2、移植算法2.1
算法简介
此算法是基于操作系统的,理论上不限于任何操作系统,只要有任务调度就可以。本文将以FreeRTOST为例来介绍本算法的使用方法。
本文所介绍的算法出处为随Cube库一起提供的,它在cube库中的位置如下图所示:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162203ex4t076poxzrqva6.jpg.thumb.jpg)
本文将以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文件添加到工程,并在工程中添加对应头文件目录:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162208uzz71woo1j5axx21.jpg.thumb.jpg)
第二步:打开FreeRTOST的配置头文件FreeRTOSConfig.h修改宏configUSE_IDLE_HOOK和configUSE_TICK_HOOK的值为1:
#defineconfigUSE_PREEMPTION 1
#defineconfigUSE_IDLE_HOOK 1 //修改此宏的值为1
#defineconfigUSE_TICK_HOOK 1 //修改此宏的值为1
#defineconfigCPU_CLOCK_HZ (SystemCoreClock )
#defineconfigTICK_RATE_HZ ( (TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 8 )
#define configMINIMAL_STACK_SIZE (( uint16_t ) 128 )
第三步:继续在FreeRTOSConfig.h头文件的末尾处添加traceTASK_SWITCHED_IN与traceTASK_SWITCHED_OUT定义:
#definetraceTASK_SWITCHED_IN() extern voidStartIdleMonitor(void); \
StartIdleMonitor()
#define traceTASK_SWITCHED_OUT() extern voidEndIdleMonitor(void); \
EndIdleMonitor()
第四步:在main.h头文件中include“”cmsis_os.h“”
Main.h :
#include "stm32f4xx_hal.h"
#include "stm324xg_eval.h"
#include "cmsis_os.h" //添加包含此头文件
//…
第五步:修改工程属性,使编译过程不需要函数原型:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162214wqvrpvqiqv0bpala.jpg.thumb.jpg)
第六步:在工程中任何用户代码处都可以调用osGetCPUUsage()函数来获取当前CPU的使用率:
static void LED_Thread2(void const *argument)
{
uint32_t count;
uint16_t usage =0;
(void) argument;
for(;;)
{
count =osKernelSysTick() + 10000;
/* Toggle LED2 every500 ms for 10 s */
while (count >=osKernelSysTick())
{
BSP_LED_Toggle(LED2);
osDelay(500);
}
usage =osGetCPUUsage(); //获取当前CPU的使用率
/* Turn off LED2 */
BSP_LED_Off(LED2);
/* Resume Thread 1 */
osThreadResume(LEDThread1Handle);
/* Suspend Thread 2 */
osThreadSuspend(NULL);
}
}
第七步:编译并运行测试
在调试状态下使用Live Watch窗口监控全部变量osCPU_Usage的值:
![](http://5.eewimg.cn/data/attachment/forum/201608/12/162221u4re2rmsum441ss4.png.thumb.jpg)
osCPU_Usage是在cpu_utils.c文件中定义的全局变量,表示当前CPU的使用率,是个动态值,由上图可以,CPU使用率的动态值为20%。实际在代码中是按第六步中调用osGetCPUUsage()函数来获取当前CPU的使用率的。
至此,算法使用方法介绍完毕。
3 、算法实现原理分析
操作系统运行时是不断在不同的任务间进行切换,而驱动这一调度过程是通过系统tick来驱动的,即每产生一次系统tick则检查一下当前正在运行的任务的环境判断是否需要切换任务,即调度,如果需要,则触发PendSV,通过在PendSV中断调用vTaskSwitchContext()函数来实现任务的调度。而本文所要讲述的CPU使用率算法是通过在一定时间内(1000个时间片内),计算空闲任务所占用的时间片总量,100减去空闲任务所占百分比则为工作任务所占百分比,即CPU使用率。
void vApplicationIdleHook(void)
{
if( xIdleHandle == NULL )
{
/* Store the handle tothe idle task. */
xIdleHandle =xTaskGetCurrentTaskHandle(); //记录空闲任务的句柄
}
}
此函数为空闲任务钩子函数,每次当切换到空闲任务时就会运行此钩子函数,它的作用就是记录当前空闲任务的句柄并保存到全局变量xIdleHandle。
void vApplicationTickHook (void)
{
static int tick = 0;
if(tick ++ >CALCULATION_PERIOD) //每1000个tick,刷新一次CPU使用率
{
tick = 0;
if(osCPU_TotalIdleTime> 1000)
{
osCPU_TotalIdleTime =1000;
}
osCPU_Usage = (100 -(osCPU_TotalIdleTime * 100) / CALCULATION_PERIOD); //这行代码就是CPU使用率的具体计算方法了
osCPU_TotalIdleTime =0;
}
}
此函数为操作系统的tick钩子函数,即每次产生系统tick中断都会进入到此钩子函数。此钩子函数实际上就是具体计算CPU使用率的算法了。osCPU_TotalIdleTime是一个全局变量,表示在1000个tick时间内空闲任务总共占用的时间片,CALCULATION_PERIOD宏的值为1000,即每1000个tick时间内重新计算一次CPU的使用率。
下面两个函数就是如何计算osCPU_TotalIdleTime的:
void StartIdleMonitor(void)
{
if( xTaskGetCurrentTaskHandle() ==xIdleHandle ) //如果是切入到空闲任务
{
osCPU_IdleStartTime =xTaskGetTickCountFromISR();//记录切入到空闲任务的时间点
bd84
}
}
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的运行性能
原文地址:http://bbs.eeworld.com.cn/thread-497511-1-1.html
本文章系转载,如有侵权,请原作者联系,删除。
相关文章推荐
- 一种基于FreeRTOS的CPU使用率测算方法及原理介绍
- 基于生长的棋盘格角点检测方法--(1)原理介绍
- 基于PHP扩展一种处理Emoji方法的类库介绍【Carmela】
- 基于生长的棋盘格角点检测方法--(1)原理介绍 .
- 【代码分享】一种异常值检测方法、原理 (基于箱线图)
- [原创]一种基于Python爬虫和Lucene检索的垂直搜索引擎的实现方法介绍
- 一种基于空间数据库和SVG的高速Web电子地图的生成及应用方法
- 一种基于局部最小代价分水岭变换的图像分割新方法 阅读笔记
- 一种快速的未登陆词识别方法(原理和实现)
- 本文介绍了一种利用Repeater控件显示主-从关系数据表的方法。
- 内部文件检索——公司经验管理系统的一种有效方法
- DoS攻击原理以及常见方法介绍
- VC《介绍一种巧妙的删除程序自己的方法》 - 电脑教程 - 天天加油
- 介绍一种在大循环就可实现的简单多任务编程方法
- 几个DSP高手的经验介绍,编写基于DSP程序的注意事项
- 一种基于SPC的软件过程质量分析方法 推荐
- 大型多玩家在线游戏,第 1 部分: 一种基于性能的基础结构规模评估方法
- DoS攻击原理以及常见方法介绍(二)
- 介绍一种巧妙的删除程序自己的方法
- 几个DSP高手的经验介绍,编写基于DSP程序的注意事项