RT-Thread: CPU 使用率应用

关键词: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()函数中加个延时。

RT-Thread: CPU 使用率应用_第1张图片RT-Thread: CPU 使用率应用_第2张图片

1. CPU 利用率的基本概念:

        CPU 利用率(使用率)是系统运行的程序占用的 CPU 资源,表示机器在某段时间程序运行的情况。

2. CPU 利用率的作用:

        CPU 利用率一定要合理。CPU 利用率不能一直接近 100%,如果这时有一个紧急的任务要临时插入,就可能因为 CPU 被占满导致这个紧急任务无法被响应;CPU利用率也不能太低,比如一直保持在 1% 以下,这样我们会认为这种产品的资源过于浪费。

3. CPU 利用率统计:

        RT-Thread 提供了一个统计 CPU 利用率的代码文件,其工作原理为:在空闲线程中计算出一段时间内处于空闲线程的时间,从而得出 CPU 的占用率。

4. 将代码导入工程:

        将以下源码添加到工程中。

cpuusage.c

#include 
#include 

#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

RT-Thread: CPU 使用率应用_第3张图片

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,后面的就是统计后的真正数据。

你可能感兴趣的:(RT-Thread,RT-Thread)