WinCE OAL中的电源管理函数(转)

本文详细介绍了WinCE操作系统中的电源管理机制,重点分析了OEMIdle和OEMPowerOff两个核心函数的工作原理及其实现细节。OEMIdle用于处理器级电源管理,通过使处理器进入低功耗状态来节省电力;OEMPowerOff则实现更深层次的系统级电源管理。

WinCE OAL中的电源管理函数

WinCE OAL中的电源管理主要由OEMIdleOEMPowerOff两个函数实现。应该说OEMIdle实现的是处理器级的电源管理,而OEMPowerOff实现的是板级的电源管理。

WinCE系统运行的时候,如果没有任何线程可以执行,那么内核就会调用OEMIdle函数。一般在OEMIdle中,处理器都会进入sleep模式或者idle模式,这取决于处理器本身所能支持的低功耗模式。应该说,这个时候系统中的各个设备还是正常工作的,只是处理器进入了一种低功耗模式。OEMIdle函数是OAL中必须实现的,微软也提供了一个例子,在%_WINCEROOT%/Platform/Common/Src/Common/Timer/Idle路径下,下面就这个例子简单分析一下:

 void OEMIdle(DWORD idleParam)

{

   UINT32 baseMSec, idleMSec, idleSysTicks;

   INT32 usedCounts, idleCounts;

   ULARGE_INTEGER idle;

 

   //保存当前系统的毫秒数

   baseMSec = CurMSec;

 

   //根据下一次调度的时间计算出当前空闲的时间

   idleMSec = dwReschedTime - baseMSec;

   

   //如果没有空闲时间,直接返回

   if ((INT32)idleMSec <= 0) return;

 

   //如果空闲时间超过了硬件Timer的最大技术,则以硬件Timer的最大计数为准

   if (idleMSec > g_oalTimer.maxPeriodMSec) {

       idleMSec = g_oalTimer.maxPeriodMSec;

   }

   

   //计算空闲时间相当于多少系统tick

   idleSysTicks = idleMSec/g_oalTimer.msecPerSysTick;

   

   //计算空闲时间相当于多少个Timercount

   idleCounts = idleSysTicks * g_oalTimer.countsPerSysTick;

 

   //已经流逝了多少个Timercount

   usedCounts = OALTimerCountsSinceSysTick();

 

   //判断空闲时间大于1个系统tick

   if (idleSysTicks > 1) {

       //调用OALTimerUpdate函数更新硬件Timercount,延长为空闲时间

       OALTimerUpdate(idleCounts, g_oalTimer.countsMargin);

       //更新实际的系统tick的毫秒数和count

       g_oalTimer.actualMSecPerSysTick = idleMSec;

       g_oalTimer.actualCountsPerSysTick = idleCounts;

   }

 

//处理器进入Idle模式,并等待中断唤醒,此期间可能被其他中断唤醒,也可能

//等到空间时间过去后,由系统Timer中断唤醒

   OALCPUIdle();

 

   //判断空闲时间大于1个系统tick

   if (idleSysTicks > 1) {

 

       //如果产生的中断不是系统Timer中断

       if (CurMSec == baseMSec) {

           //调用OALTimerUpdate函数更新硬件Timer为原来的计数值

           idleSysTicks = OALTimerUpdate(

               g_oalTimer.countsPerSysTick, g_oalTimer.countsMargin

           );

           //恢复相关变量赋值

           g_oalTimer.actualMSecPerSysTick = g_oalTimer.msecPerSysTick;

           g_oalTimer.actualCountsPerSysTick = g_oalTimer.countsPerSysTick;

           //更新CurMSecidleCounts

           CurMSec += idleSysTicks * g_oalTimer.actualMSecPerSysTick;

           idleCounts = idleSysTicks * g_oalTimer.actualCountsPerSysTick;

           g_oalTimer.curCounts += idleCounts;

           idleCounts += OALTimerCountsSinceSysTick();

       }           

 

   } else {

 

       if (CurMSec == baseMSec) {

          //不是系统Timer中断,只更新idleCounts

           idleCounts = OALTimerCountsSinceSysTick();

       }           

 

   }

 

   //获得实际的空闲的count

   idleCounts -= usedCounts;

   if (idleCounts < 0) idleCounts = 0;

   

   //更新64位计数器的计数值

   idle.LowPart = curridlelow;

   idle.HighPart = curridlehigh;

   idle.QuadPart += idleCounts;

   curridlelow = idle.LowPart;

   curridlehigh = idle.HighPart;

}

 

 

在该函数中调用了两个重要的函数,以前没有提到,这里说一下:

UINT32 OALTimerUpdate(UINT32 period, UINT32 margin)

period:要更新的计数值

margin:硬件Timer被改变所需的count

该函数主要用于更新硬件Timer的计数值,实际上就改变了硬件Timer产生中断的频率。

 

VOID OALCPUIdle()

该函数主要实现了硬件处理器进入Idle模式,进入Idle模式后,处理器会停止执行在该函数中,直到中断产生后,处理器从Idle模式恢复到正常模式,然后从该函数中返回。

 

关于OEMIdle函数,这里向大家推荐一篇不错的blog,供大家参考:

http://blogs.gotdotnet.com/ce_base/archive/2006/11/15/optimizing-oemidle-for-lower-power-consumption.aspx

 

blog主要介绍了一种实现OEMIdle的思想。OEMIdle函数的实现依赖于处理器所支持的低功耗模式。有些处理器支持多种低功耗模式,根据需要可以在OEMIdle中实现。但是要知道进入低功耗后恢复到正常模式下所花费的时间会影响到整个系统的实时性,所以有时候要根据自己的产品需求,在省电和实时性之间做一个取舍。

 

 

OAL中还有一个重要的函数OEMPowerOff。当系统进入Suspend的时候,首先所有的驱动的PowerDown函数会被调用,然后就会调用OEMPowerOff函数。在该函数中,处理器会进入深度休眠,直到中断产生后,处理器恢复到正常工作模式,从该函数中返回,接下来所有驱动的PowerUp函数会被调用,然后系统恢复正常工作模式。

void OEMPowerOff (void)

该函数的实现流程如下:

 

  • 如果支持KITL,调用OALKitlPowerOff关闭KITL功能
  • 调用BSPPowerOff函数关闭板级的相关电源
  • 保存所有寄存器的值
  • 关闭所有中断,清除所有中断标记位
  • 打开能够唤醒处理器的中断
  • SDRAM进入自刷新模式
  • 处理器进入深度休眠模式,停止执行,等待中断唤醒
  • 中断产生后,处理器被唤醒,并恢复到正常模式
  • SDRAM进入正常工作模式
  • 打开并配置系统的相关中断
  • 恢复所有寄存器得值
  • 调用BSPPowerOn函数打开板级的相关电源
  • 如果支持KITL,调用OALKitlPowerOn重新初始化KITL

下载方式:https://pan.quark.cn/s/b4d8292ba69a 在构建食品品牌的市场整合营销推广方案时,我们必须首先深入探究品牌的由来、顾客的感知以及市场环境。 此案例聚焦于一款名为“某饼干产品”的食品,该产品自1998年进入河南市场以来,经历了销售业绩的波动。 1999至2000年期间,其销售额取得了明显的上升,然而到了2001年则出现了下滑。 在先前的宣传活动中,品牌主要借助大型互动活动如ROAD SHOW来吸引顾客,但收效甚微,这揭了宣传信息与顾客实际认同感之间的偏差。 通过市场环境剖析,我们了解到消费者对“3+2”苏打夹心饼干的印象是美味、时尚且充满活力,但同时亦存在口感腻、价位偏高、饼身坚硬等负面评价。 实际上,该产品可以塑造为兼具美味、深度与创新性的休闲食品,适宜在多种情境下分享。 这暗着品牌需更精确地传递产品特性,同时消解消费者的顾虑。 在策略制定上,我们可考虑将新产品与原有的3+2苏打夹心进行协同推广。 这种策略的长处在于能够借助既有产品的声誉和市场占有率,同时通过新产品的加入,刷新品牌形象,吸引更多元化的消费群体。 然而,这也可能引发一些难题,例如如何合理分配新旧产品间的资源,以及如何保障新产品的独特性和吸引力不被既有产品所掩盖。 为了提升推广成效,品牌可以实施以下举措:1. **定位修正**:基于消费者反馈,重新确立产品定位,突出其美味、创新与共享的特性,减少消费者感知的缺陷。 2. **创新宣传**:宣传信息应与消费者的实际体验相契合,运用更具魅力的创意手段,例如叙事式营销,让消费者体会到产品带来的愉悦和情感共鸣。 3. **渠道选择**:在目标消费者常去的场所开展活动,例如商业中心、影院或在线平台,以提高知名度和参与度。 4. **媒体联...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值