关键词:RT-Thread cpu使用率,cpuusage.c , cpuusage.h
说明:使用 RT-Thread 希望知道 mcu 计算能力的使用率或cpu使用率。
注意:在调试CUP使用率时,根据参考资料移植了 cpuusage.c , cpuusage.h ,也调用了 void cpu_usage_init() 初始化CPU使用率函数,但 cpu_usage_get() 返回的值始终为 0 ,调试时发现 rt_thread_idle_entry()系统没有进入空闲线程,经过查参考资料里面的提示,原因是 FINSH 控制台组件在空闲时始终在等待接收字符,导致 空闲线程得不到运行。
解决办法:在 rt_hw_console_getchar()函数中加个延时。
1. CPU 利用率的基本概念:
CPU 利用率(使用率)是系统运行的程序占用的 CPU 资源,表示机器在某段时间程序运行的情况。
2. CPU 利用率的作用:
CPU 利用率一定要合理。CPU 利用率不能一直接近 100%,如果这时有一个紧急的任务要临时插入,就可能因为 CPU 被占满导致这个紧急任务无法被响应;CPU利用率也不能太低,比如一直保持在 1% 以下,这样我们会认为这种产品的资源过于浪费。
3. CPU 利用率统计:
RT-Thread 提供了一个统计 CPU 利用率的代码文件,其工作原理为:在空闲线程中计算出一段时间内处于空闲线程的时间,从而得出 CPU 的占用率。
4. 将代码导入工程:
将以下源码添加到工程中。
cpuusage.c
#include <rtthread.h>
#include <rthw.h>#define CPU_USAGE_CALC_TICK 10
#define CPU_USAGE_LOOP 100static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0;
static rt_uint32_t total_count = 0;static void cpu_usage_idle_hook()
{rt_tick_t tick;rt_uint32_t count;volatile rt_uint32_t loop;if (total_count == 0){/* get total count */rt_enter_critical();tick = rt_tick_get();while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK){total_count ++;loop = 0;while (loop < CPU_USAGE_LOOP) loop ++;}rt_exit_critical();}count = 0;/* get CPU usage */tick = rt_tick_get();while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK){count ++;loop = 0;while (loop < CPU_USAGE_LOOP) loop ++;}/* calculate major and minor */if (count < total_count){count = total_count - count;cpu_usage_major = (count * 100) / total_count;cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count;}else{total_count = count;/* no CPU usage */cpu_usage_major = 0;cpu_usage_minor = 0;}
}void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor)
{RT_ASSERT(major != RT_NULL);RT_ASSERT(minor != RT_NULL);*major = cpu_usage_major;*minor = cpu_usage_minor;
}void cpu_usage_init()
{/* set idle thread hook */rt_thread_idle_sethook(cpu_usage_idle_hook);
}
cpuusage.h
#ifndef __CPUUSAGE_H__
#define __CPUUSAGE_H__#define CPU_UPDATE 1void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor);
void cpu_usage_init(void);#endif /*__ADC_H__ */
直接编译,可能有报错,在 rtconfig.h 中开启如下选项
#define RT_USING_HOOK
#define RT_USING_IDLE_HOOK
5. CPU 利用率统计实验
实验通过一个线程里的延时(通过 for 循环实现)代码来模拟占用 CPU 资源,另外再创建一个线程来读取 CPU 利用率并打印。
#include "board.h"
#include "rtthread.h"
#include "cpuusage.h"// 定义线程控制块指针
static rt_thread_t led_thread = RT_NULL;
static rt_thread_t cpu_usage_thread = RT_NULL;/******************************************************************************
* @ 函数名 : led_thread_entry
* @ 功 能 : 线程入口函数
* @ 参 数 : parameter 外部传入的参数
* @ 返回值 : 无
******************************************************************************/
static void led_thread_entry(void *parameter)
{rt_uint16_t i;while(1){LED0_TOGGLE; // LED0 电平切换for(i = 0; i < 20000; i++); // 模拟占用 CPU 资源rt_thread_delay(10); // 10个tick(10ms)}
}/******************************************************************************
* @ 函数名 : cpu_usage_thread_entry
* @ 功 能 : 线程入口函数
* @ 参 数 : parameter 外部传入的参数
* @ 返回值 : 无
******************************************************************************/
static void cpu_usage_thread_entry(void *parameter)
{rt_uint8_t major, minor;while(1){// 获取 CPU 利用率cpu_usage_get(&major, &minor);rt_kprintf("CPU 利用率:%d.%d %\r\n", major, minor);rt_thread_delay(500); // 500个tick(500ms)}
}int main(void)
{// 硬件初始化和RTT的初始化已经在component.c中的rtthread_startup()完成// CPU 使用率统计初始化cpu_usage_init();// 创建一个动态线程led_thread = // 线程控制块指针rt_thread_create("led_thread", // 线程名字led_thread_entry, // 线程入口函数RT_NULL, // 入口函数参数255, // 线程栈大小4, // 线程优先级20); // 线程时间片// 开启线程调度if(led_thread != RT_NULL)rt_thread_startup(led_thread);elsereturn -1;// 创建一个动态线程cpu_usage_thread = // 线程控制块指针rt_thread_create("cpu_usage_thread", // 线程名字cpu_usage_thread_entry, // 线程入口函数RT_NULL, // 入口函数参数255, // 线程栈大小5, // 线程优先级20); // 线程时间片// 开启线程调度if(cpu_usage_thread != RT_NULL)rt_thread_startup(cpu_usage_thread);elsereturn -1;
}
实验现象
注意:在开始的时候调用获取 CPU 利用率函数 cpu_usage_get() 是会进行一个计算参考值的,所以刚开始的时候 CPU 利用率为 0,后面的就是统计后的真正数据。