完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、前言 出于性能方面的考虑,有的时候,我们希望知道CPU的使用率为多少,进而判断此CPU的负载情况和对于当前运行环境是否足够“胜任”。本文将介绍一种计算CPU占有率的方法以及其实现原理。 此算法是基于操作系统的,理论上不限于任何操作系统,只要有任务调度就可以。本文将以FreeRTOST为例来介绍本算法的使用方法。 本文所介绍的算法出处为随Cube库一起提供的,它在cube库中的位置如下图所示: 本文将以STM32F4为例,测试环境为STM3240G-EVAL评估板。 2.2 、开始移植 本文以CubeF4内的示例代码工程STM32Cube_FW_F4_V1.10.0ProjectsSTM324xG_EVALApplicationsFreeRTOSFreeRTOS_ThreadCreation为例,IDE使用IAR。 第一步: 使用IAR打开FreeRTOS_ThreadCreation工程,将cpu_utils.c文件添加到工程,并在工程中添加对应头文件目录: 第二步:打开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" //添加包含此头文件 //… 第五步:修改工程属性,使编译过程不需要函数原型: 第六步:在工程中任何用户代码处都可以调用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的值: osCPU_Usage是在cpu_utils.c文件中定义的全局变量,表示当前CPU的使用率,是个动态值,由上图可以,CPU使用率的动态值为20%。实际在代码中是按第六步中调用osGetCPUUsage()函数来获取当前CPU的使用率的。 至此,算法使用方法介绍完毕。 操作系统运行时是不断在不同的任务间进行切换,而驱动这一调度过程是通过系统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();//记录切入到空闲任务的时间点 } } 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的运行性能。 |
|
|
|
644 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1819 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1262 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
1136 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1357 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12026 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 08:07 , Processed in 0.724587 second(s), Total 63, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号