********************************LoongEmbedded************************
作者:LoongEmbedded(kandi)
时间:2011.03.07
类别:WINCE嵌入式系统开发
********************************LoongEmbedded************************
1. WINCE电源管理的架构
图1
使用电源管理器,设备可以接收电源状态改变的通知,这个通知是以I/O控制的方式(IOCTL控制码)的方式来和设备驱动通信的。因为I/O控制运行在线程上下文环境中,驱动开发者可以很灵活去实现电源状态的改变。使用I/O控制的方式来管理电源也可以让设备电源状态独立于整体的OS电源状态。所以,当OS在运行的时候一些设备可以关闭,而在OS挂起的时候一些设备可以继续保持正常的工作状态。
电源管理器除了管理设备电源之外,它可以通知应用程序相关的电源事件,比如,当OS从挂起的状态恢复的时候,电源管理器会通知感兴趣的应用程序。电源管理器作为设备驱动和应用程序的中间层(传递者),它定义了OS电源状态,并且在这三者之间的通信中实现下面这些功能
⑴OS电源状态决定了所有的设备的最大的电源消耗。
⑵应用程序通过强制限制特定的设备最小的电源功耗来让此设备获得最小的性能水平。
⑶电源管理器允许设备聪明地管理自己的电源,只要设备的电源等级在最大和最小的限制值之间。
⑷如果设置最小的电源功耗大于它本身的最大值,只要应用程序需要设备,那么这个设备就会保持在高的电源功耗状态。
⑸设备可以有一个或者多个设备电源状态,但被限制在D0到D4之间。
⑹如果OS转变为挂起的状态,应用程序决定设备的最小功耗的限制。
设备驱动可以调用DevicePowerNotify函数来调整设备自身的功耗水平,并且应用程序可以调用SetPowerRequirement来核实设备需要运行在可以受的性能水平上。
WinCE电源管理器通过一个名为Pm.dll的动态链接库与设备管理器Device.exe链接。Pm.dll动态链接库支持三类接口:一是驱动程序接口:为需要进行电源管理的设备的驱动程序使用;二是应用程序接口:为需要利用电源管理的应用程序使用;三是提醒接口(Notification):为需要接受电源事件提醒的应用程序使用。
2. 系统电源状态
系统电源状态明确指定了系统中所有设备的最大设备电源状态,并且由OEM来定义系统的电源状态,而系统电源状态大概有以下几种
⑴on
用户与系统交互时的状态,在common.reg中的相关信息如下:
图2
⑵BacklightOff
在一段时间内,如果一直没有用户操作(比如按下某个键或者触摸屏幕),就关闭背光,这时其他的设备也可以关闭,这需要看设计的需要了,这个timeout值可以通过控制面板进行设置。
⑶ UserIdle
在一段时间内,如果一直没有用户操作,LCD屏工作在低功耗模式或者关闭显示 (这取决于OEM的设计了),在common.reg中的相关信息如下:
图3
⑷ SystemIdle
用户没有直接使用系统,这种状态下认为设备处于空闲的状态,当处理器仍然在工作,比如在进行文件传输,在common.reg中的相关信息如下:
图4
⑸Suspended
睡眠状态,没有线程在运行。CPU处于idle的状态,这时候只能通过硬件的唤醒中断才能唤醒系统。
图5
3. 设备电源状态
设备电源状态是预先定义的,电源管理器递给一个设备状态给设备驱动,然后这个驱动负责根据设备的能力来映射为相应的电源状态,并且让设备工作在恰当的电源状态下。
⑴Full on
D0,此状态表示设备已开启或正在运行,系统要求设备工作在最大功耗和最高性能的状态。
⑵Low on
D1,此状态表示设备已开启或正在运行,但以低于D0状态的功耗及性能运行。D1状态适用于设备已经被使用,但以较低的性能运行即可,没有必要以最大性能运行,会产生额外的功率消耗。
⑶Standby
D2,此状态表示设备被部分供电,且设备在需要时可以自动唤醒。
⑷Sleep
D3,睡眠状态。保证唤醒的最小供电,在需要时能自动唤醒并初始化。
⑸Off
D4,关闭状态,不供电。
图6
4. 电源管理器接口
4.1 应用程序电源管理接口
应用程序可以利用这些接口来调整系统及设备的电源状态,这些接口中,只有GetSystemPowerState()、SetPowerRequirement()和ReleasePowerRequirement()函数是为一般的应用程序设计的。比如,应用程序可以调用SetSystemPowerState函数来挂起系统,但电源管理器可以限制应用程序请求系统进入挂起状态的情况,所以其他一些应用程序电源管理接口函数SetSystemPowerState()、GetDevicePower ()和SetDevicePower()是为OEM应用来设计的,比如控制面板应用程序,下面来学习这些函数
⑴GetSystemPowerState函数
这个函数用户返回系统电源状态(比如是on),在power按键驱动中加入下面的代码
dwErr = GetSystemPowerState(wPState, 20, &dFlag);
输出的wPState=“on”,dFlag=0x12010000,这个dFlag的值表示什么意思呢?见下图
是在pm.h下定义的
图7
⑵SetSystemPowerState函数
SetSystemPowerState函数可被OEM程序或者其他应用程序调用,来把系统电源状态设置为需要值,相关描述见VS2005中的相关文档
图8
如可以像下面一样来使用
Result = SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
⑶SetPowerRequirement函数
调用SetSystemPowerState是一个直接改变电源状态的方法。更巧妙的方法是通过调用SetPowerRequirement来请求系统维持应用程序所需最低限度的电源状态。SetSystemPowerState是假定应用程序知道所需状态,而调用SetPowerRequirement是允许系统对电源设定做优化以满足应用程序的需要。一个使用SetPowerRequirement会比较方便的例子是,一个使用串口的应用程序需要串口在进行通信时保持住电源状态。SetPowerRequirement被定义如下
图9
第一个参数指定了应用程序需要维护电源状态的设备。DeviceState参数定义了设备的电源状态。CEDEVICE_POWER_STATE指定了状态范围是从D0(意味着设备是处于最大功耗状态)到D4(表示设备被关闭)(译者注:其实D0到D4的状态的具体表现,完全是由OEM厂商可自定义的,对应用程序开发者来说,比如是在D1关LCD背光还是在D2,都是不确定的,微软只给出标准定义,而不是实际定义)。DeviceFlags参数由两个标志合并而成:POWER_NAME,表示设备名有效;POWER_FORCE,表示设备应当维持当前状态甚至当系统挂起时。如果pvSystemState不为NULL