ucos中的CPU利用率与实现原理


  在PC机上,大家可以通过任务管理器查看自己电脑的性能参数,如CPU利用率、内存占用、硬盘以及以太网吞吐量等,往往开的软件越多,CPU利用率就越高。在单片机上运行嵌入式操作系统之后,也一样可以查看自己的单片机CPU利用率,就是OSCPUUsage。这个CPU利用率同样可以反应程序占用CPU资源的情况,利用率越高时,该值就越大,利用率越低时,该值就越小;而单片机的RAM使用情况反应的就是其内存的占用,如果RAM过高的时候,需要通过优化变量及更改堆栈空间大小来减小内存占用。

  这里只说一下单片机获取CPU占用率OSCPUUsage值的实现原理,以uC/OS-II嵌入式操作系统为例,按照系统任务类型划分,除了用户任务之外还有一个空闲任务和一个统计任务,在OSInit();中有两个函数分别为:OS_InitTaskIdle();与OS_InitTaskStat();空闲任务系统都是会建立的,该任务就是当某段时间内,CPU没有用户任务需要处理的时候,就会执行空闲任务,但是要获得OSCPUUsage值必须还要建立统计任务,如果用户程序打算使用统计任务,那么就必须在主函数当中只建立一开始任务start_task,在开始任务start_task();中调用OSStatInit(),之后建立其他用户自己的任务。
  其中在os_cfg.h中需要使能OS_TASK_STAT_EN,这样在OSInit();中就可以实现统计任务的创建OS_InitTaskStat();,该任务具有倒数第二高的优先级,只比空闲任务优先级高。该任务会通过for (;;){}来实现单位时间内(1/10秒内)空闲任务的计数,并通过OSCPUUsage   = (INT8U)(100uL - OSIdleCtrRun / OSIdleCtrMax);计算得到CPU使用率。其中OSIdleCtrMax是系统最大空闲率,在前面的OSStatInit()中通过计算获取,这就是具体的实现原理。
  获取:OSIdleCtrMax 值
void  OSStatInit (void)

{

#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */

    OS_CPU_SR  cpu_sr = 0u;

#endif



    OSTimeDly(2u);                               /* Synchronize with clock tick                        */

    OS_ENTER_CRITICAL();

    OSIdleCtr    = 0uL;                          /* Clear idle counter                                 */

    OS_EXIT_CRITICAL();

    OSTimeDly(OS_TICKS_PER_SEC / 10u);           /* Determine MAX. idle counter value for 1/10 second  */

    OS_ENTER_CRITICAL();

    OSIdleCtrMax = OSIdleCtr;                    /* Store maximum idle counter count in 1/10 second    */

    OSStatRdy    = OS_TRUE;

    OS_EXIT_CRITICAL();

}

 计算OSCPUUsage :

void  OS_TaskStat (void *p_arg)

{

#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */

    OS_CPU_SR  cpu_sr = 0u;

#endif







    p_arg = p_arg;                               /* Prevent compiler warning for not using 'p_arg'     */

    while (OSStatRdy == OS_FALSE) {

        OSTimeDly(2u * OS_TICKS_PER_SEC / 10u);  /* Wait until statistic task is ready                 */

    }

    OSIdleCtrMax /= 100uL;

    if (OSIdleCtrMax == 0uL) {

        OSCPUUsage = 0u;

#if OS_TASK_SUSPEND_EN > 0u

        (void)OSTaskSuspend(OS_PRIO_SELF);

#else

        for (;;) {

            OSTimeDly(OS_TICKS_PER_SEC);

        }

#endif

    }

    for (;;) {

        OS_ENTER_CRITICAL();

        OSIdleCtrRun = OSIdleCtr;                /* Obtain the of the idle counter for the past second */

        OSIdleCtr    = 0uL;                      /* Reset the idle counter for the next second         */

        OS_EXIT_CRITICAL();

        OSCPUUsage   = (INT8U)(100uL - OSIdleCtrRun / OSIdleCtrMax);

        OSTaskStatHook();                        /* Invoke user definable hook                         */

#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)

        OS_TaskStatStkChk();                     /* Check the stacks for each task                     */

#endif

        OSTimeDly(OS_TICKS_PER_SEC / 10u);       /* Accumulate OSIdleCtr for the next 1/10 second      */

    }

}

在MDK中进行系统调试DEBUG的时候。也可以将OSCPUUsage右击添加到watch窗口中进行查看,来实时监测CPU利用率,如果多任务是采用OSTimeDly();延时函数进行就绪,可以按照实际需要通过调节延时值来调整CPU利用率,对于一些不必要一直运行的任务,可以通过等待信号量的方式进行就绪,这样可以降低利用率,让需要的运行的任务可以及时得到运行。


MDK调试watch窗口:

---------------------
作者:forgot
链接:https://bbs.21ic.com/icview-3285226-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值