RT-Thread CPU占用率

RT-Thread Nano 环境下 CPU占用率统计方法。
编者:张永辉  2021年5月25日
说明:自创方法,统计CPU使用率
代码: PRJ_0_RTT_nano_FinSH_cpu usage
--------------------------------------------------------------------------------
理论:
   1 CPU空闲时总是运行idle线程,开启外挂后,idle会不停的调用外挂钩子
   2 首次调用hook时,
     关闭任务切换,计算A变量加到1百万需要使用的tick数。比如用了500个tick这么久。cpu_min_cnt = 500

   3 然后每次调用hook时,
     开启任务切换,计算B变量加到1百万需要使用的tick数。比如用了620个tick, cpu_run_cnt = 620
     在B自加期间,有自行其他任务,所以本次的tick当然会大于500,
     多出的tick数,则是CPU不空间的占用时间

   4 计算CPU占用率
     比如CPU用了620个周期中,其中120个周期是其他任务占用了的,所以cpu_usage= (620-500)/620=19.35%

   5 关键代码
     A B变量的自加过程必须一样,否则不具备可比性,比如本文中两个代码如下:
     【A】
        rt_enter_critical();
        tick_tmp = rt_tick_get();
        while(++cpu_min_cnt < CPU_CNT) {}       //CPU耗时
        cpu_min_cnt = rt_tick_get() - tick_tmp;
        rt_exit_critical();
     【B】
        tick_tmp = rt_tick_get();
        while(++cpu_run_cnt < CPU_CNT) {}       //CPU耗时
        cpu_run_cnt = rt_tick_get() - tick_tmp;
     区别仅仅是是否有任务切换

   6 实际效果,
     RT_TICK_PER_SECOND =1000, GD32F405运行在120M时的 CPU占用率约 0.1%
     LED任务中加入1个  a=0;while(++a<100000); 的耗时操作后,CPU占用率约 10.2%
     LED任务中加入2个  a=0;while(++a<100000); 的耗时操作后,CPU占用率约 19.7%
     LED任务中加入4个  a=0;while(++a<100000); 的耗时操作后,CPU占用率约 26.8%

   7 不足:本方法统计周期不是1秒,而是变量加到CPU_CNT的为止的时间,CPU_CNT值越大,统计时间越长就越准确.
     如果其他任务CPU占用到90%,统计时间将延长9倍。


   8 也还有改进之处,,欢迎大家指点。
--------------------------------------------------------------------------------
1 rtconfig.h 中使能 RT_USING_HOOK宏定义,开启系统钩子功能。
2 board.c 的rt_hw_board_init
  调用初始化函数borad_cpu_usage_init();
3 添加两个文件到工程
  [broad_cpu_usage.h]
    #ifndef __BROAD_CPU_USAGE_H__
    #define __BROAD_CPU_USAGE_H__
    void borad_cpu_usage_init(void);
    int  board_cpu_usage_get(char *major, char *minor);
    void cpu_usage_idle_hook(void);
    #endif

  [broad_cpu_usage.c]
    #include "gd32f10x_it.h"
    #include
    //****
    #define CPU_CNT 5000000
    int cpu_min_cnt = 0;            //变量加CPU_CNT次,需要的最小tick数
    int cpu_run_cnt = 0;            //变量加CPU_CNT次,运行了的tick数
    int cpu_usage = 0;              //CPU占用率,,千分之N
    void cpu_usage_idle_hook(void);

    //初始化,rt_hw_board_init 调用
    void borad_cpu_usage_init(void)
    {
        rt_thread_idle_sethook(cpu_usage_idle_hook);
    }
    //获取CPU占用率 (千分之N)
    int  board_cpu_usage_get(char *major, char *minor)
    {
        return cpu_usage;
    }
    //IDLE外挂函数,CPU空闲时会被实时调用
    void cpu_usage_idle_hook(void)
    {
        rt_tick_t tick_tmp = rt_tick_get();
        //将rt_ticks 从0加到RT_TICK_MAX,,需要的tick数
        if(cpu_min_cnt==0)
        {
            rt_enter_critical();                    //关闭CPU切换,但是sys_tick是没有关闭的
            tick_tmp = rt_tick_get();
            while(++cpu_min_cnt < CPU_CNT) {}       //CPU耗时
            cpu_min_cnt = rt_tick_get() - tick_tmp; //统计占用了的最小ticks数
            rt_exit_critical();
        }

        //实时运行
        cpu_run_cnt = 0;
        tick_tmp = rt_tick_get();
        while(++cpu_run_cnt < CPU_CNT) {}           //CPU耗时
        cpu_run_cnt = rt_tick_get() - tick_tmp;     //运行期间,占用了的tick数

        //计算占用率
        cpu_usage = ((cpu_run_cnt - cpu_min_cnt)*1000 )/cpu_run_cnt;  //使用整数表示.   50/1000 = 5%的占用率
        rt_kprintf("cpu_usage = %d/1000\r\n" , cpu_usage);
    }

4 编译运行即可。
 

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