社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 精华区
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
搜索
查看: 1155|回复: 0

[原创] 【LPC54100】事件驱动之CPU使用率计算及频率调整

[复制链接]

500

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2015-4-7 10:51:28 | 显示全部楼层 |阅读模式

首先说下在RT-Thread中如何计算CPU使用率的,它先在关闭中断的情况下,在一个时间片内(比如100ms),对一个基准变量进行循环累加,得出最大的基准累加值。然后系统正常运行,在Idle任务中对另一个变量进行累加,时间片结束时,累加停止,与基准累加值计算,得出CPU使用率。


这种计算得出的cpu使用率,由于时间片较大,一般是用于调试或交互的信息输出。


在事件驱动机制中,由于除中断外所有待处理任务都会被放在vsfsm_evtq_head链表中,程序可以很清楚的知道下一刻是否有任务需要执行。这种情况下,只要提供一个us级的硬件定时器,并将其中断周期设置为我们所需要的时间片长度(如2ms),然后,当程序在空闲(vsfsm_evtq_head链表为空)和运行(vsfsm_evtq_head链表非空)两种状态间切换时,可以获得本次状态所维持的us时间,进行累加记录。当一个时间片结束时,就可以通过两种状态的总维持时间获得CPU的使用/空闲率了。当然这个比率是将中断剔除在外的,并不是十分的精确。


与RT-Thread中不一样,事件驱动中的cpu使用率并不仅仅是给大家看的,这个使用率可以用来动态调整cpu的工作频率。当使用率高时,我们可以提高cpu频率,当使用率低时,可以降低cpu频率。通过辅以一个较好的时间片长度和频率调整规则,便可以让cpu长时间工作在低频率状态下,并可以非常快的提升频率以响应重负载任务。


但是,如果系统一直处于可休眠状态,这个cpu频率动态调整的意义就不是很大,当系统不可休眠时,cpu降频将是一个非常好的节能方案。


参考代码:

  1. // vsfsm_get_event_pending should be called with interrupt disabled
  2. uint32_t vsfsm_get_event_pending(void)
  3. {
  4. #if VSFSM_CFG_AUTO_FREQ_EN
  5. static void vsfsm_auto_freq_record(uint32_t is_busy);
  6.         vsfsm_auto_freq_record(vsfsm_evt_count);
  7. #endif // VSFSM_CFG_AUTO_FREQ_EN
  8.         return vsfsm_evt_count;
  9. }
复制代码
  1. #if VSFSM_CFG_AUTO_FREQ_EN
  2. static uint32_t intervalus = 10000, busyus = 0, freeus = 0;
  3. static void (*app_auto_freq_callback_int)(uint8_t rate);
  4. enum vsfsm_cpu_state_t
  5. {
  6.         CPU_STATE_FREE = 0,
  7.         CPU_STATE_BUSY = 1,
  8. } static vsfsm_cpu_state = CPU_STATE_BUSY;

  9. static void vsfsm_auto_freq_record(uint32_t is_busy)
  10. {
  11.         if ((vsfsm_cpu_state == CPU_STATE_FREE) && (is_busy != 0))
  12.         {
  13.                 //freeus += core_interfaces.core.get_increment_ustick();
  14.                 vsfsm_cpu_state = CPU_STATE_BUSY;
  15.         }
  16.         else if ((vsfsm_cpu_state != CPU_STATE_FREE) && (is_busy == 0))
  17.         {
  18.                 //busyus += core_interfaces.core.get_increment_ustick();
  19.                 vsfsm_cpu_state = CPU_STATE_FREE;
  20.         }
  21. }

  22. static void vsfsm_auto_freq_callback_int(uint32_t us)
  23. {
  24.         uint8_t cpu_rate; // 0 -> 0%, 1 -> 0.5%, ..., 200 -> 100%
  25.         if (vsfsm_cpu_state == CPU_STATE_FREE)
  26.         {
  27.                 freeus += us;
  28.         }
  29.         else if (vsfsm_cpu_state != CPU_STATE_FREE)
  30.         {
  31.                 busyus += us;
  32.         }
  33.         cpu_rate = (busyus * 200) / intervalus;
  34.         freeus = 0;
  35.         busyus = 0;

  36.         // TODO: freq adjust
  37.         // if (cpu_rate > )
  38.         // if (cpu_rate < )

  39.         if (app_auto_freq_callback_int)
  40.                 app_auto_freq_callback_int(cpu_rate);
  41. }

  42. vsf_err_t vsfsm_auto_freq_init(uint32_t interval,
  43.                                                                 void (*callback_int)(uint8_t rate))
  44. {
  45.         if (interval < 500)
  46.                 return VSFERR_INVALID_PARAMETER;
  47.         else
  48.                 intervalus = interval;

  49.         busyus = 0;
  50.         freeus = 0;
  51.         app_auto_freq_callback_int = callback_int;
  52.         vsfsm_cpu_state = CPU_STATE_BUSY;

  53.         //return core_interfaces.core.ustick_init(interval,
  54.         //                                                                                vsfsm_auto_freq_callback_int);
  55. }
  56. #endif // VSFSM_CFG_AUTO_FREQ_EN
复制代码

工程:git.oschina.net/le062/LPCXpresso54102-leop


此帖出自NXP LPC MCU论坛
LPC4370,秒天秒地秒空气

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-9-23 06:29 , Processed in 0.221128 second(s), 16 queries , Redis On.

快速回复 返回顶部 返回列表