关键词: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 100
static 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 1
void 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);
else
return -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);
else
return -1;
}
实验现象
注意:在开始的时候调用获取 CPU 利用率函数 cpu_usage_get() 是会进行一个计算参考值的,所以刚开始的时候 CPU 利用率为 0,后面的就是统计后的真正数据。