四、设备电源管理指南
电源管理器对设备功耗、性能及响应时间没有严格的限制。然后,从用户的角度看D0和D1的状态下是可操作的。而更高的电源状态药比这两个状态消耗更少的电源。
这个简单的指南只是为了是OEM厂商能共容易的定义有意义的电源状态,而不知道每个设备的详细功耗要求。
1、设备电源自管理
一些设备自行管理其电源的过程是比较复杂的,驱动程序设计人员通常希望在设备处于休止状态时减少耗电量。降低功耗,一般也将降低设备的性能,因此,这些器件还通常要提高其性能水平。提高性能水平时也会提高功耗。
这些设备往往会动态地根据使用的周期而提高或降低其设备的电源状态。电源自管实际算法根据设备特性的不同而不同。
电源管理器的
DevicePowerNotify API函数允许驱动程序开发人员根据电源管理调整设备的电源状态。当所要求的设备的电源状态在允许的范围内即最大值和最小值之间,电源管理器将允许进行调整功率。最大值值是系统电源状态要求的值,最小值是由应用程序调用SetPowerRequirement确定。
当电源管理器决定接受设备的电源状态调整请求,电源管理器将使用该设备的API,通常使用IOCTL_POWER_SET函数更新设备的电源状态。在实际调用DevicePowerNotify时,应遵循下列准则:
· Thedevice should not update its power state if the
DevicePowerNotify callsucceeds, only when it receives an IOCTL_POWER_SET.
· Thedriver developer should not assume that a successful return code from
DevicePowerNotifyimplies that the Power Manager will issue an IOCTL_POWER_SET.
· Thedriver developer should not assume that an IOCTL_POWER_SET immediatelyfollowing a
DevicePowerNotify was issued as a result of the call.
· Devicesthat are capable of waking the system when they are put into D3 should notrequest D3 using
DevicePowerNotify.
有些设备能够支持D0到D4设备电源状态以外的其它电源等级。如果需要,这些设备的驱动程序开发人员可以将多个电源设备映射到电源管理器所能识别的某一个设备电源状态电源管理状态。设备可以不依赖电源管理器,从而在每个设备电源状态的允许范围内进行电源自管理。然而,它仍然应该使用DevicePowerNotify进行设备电源状态切换。
资管理举例:
一个实现了所有五个电源状态的设备,如果它已经一段时间内务任何活动,或其电源管理从D0降到D1或D1降到D2设备阶段,因为D2的功耗较低,而且他很少需要相应。如果设备检测到的活动,但是还不在D0状态,它会尝试去到D0。
这样的一个设备中断服务线程可能与下面的示例代码类似。
while(!fDone) {
dwStatus = WaitForSingleObject(hInterruptEvent, dwTimeout);
switch(dwStatus) {
case WAIT_OBJECT_0: // device activity
// service device
...
if(deviceDx != D0 && !fBoostRequested) {
fBoostRequested = TRUE;
DevicePowerNotify(pszDeviceName, D0, POWER_DRIVER | POWER_NAME);
}
dwTimeout = INACTIVITY_TIMEOUT;
break;
case WAIT_TIMEOUT: // device inactive
if(deviceDx < D2 && !fReductionRequested) {
fReductionRequested = TRUE;
DevicePowerNotify(pszDeviceName, deviceDx + 1, POWER_DRIVER | POWER_NAME);
}
if(deviceDx >= D2) {
dwTimeout = INFINITE;
}
default: // error handling
break;
}
}
设备的DeviceIoControl处理程序可能包含下列示例代码。
case IOCTL_POWER_SET:
// update device registers
...
deviceDx = *(PCEDEVICE_POWER_STATE) pOutBuf;
fBoostRequested = FALSE;
fReductionRequested = FALSE;
break;
上面驱动程序代码仅表明了是否请求了状态切换,而不是是否已经切换。这很重要,因为设备可能会要求在D0到D2的同时,但是由于当前的电源情况,电源管理器可能将它设置为D1。在下一次设备活动时,设备会再次请求进入D0状态,而电源管理器可能只允许其运行在D1状态。这样子能够避免在设备进入活动状态前进行额外的电源管理API调用。同样的处理逻辑也用于当设备非活动超时时电源状态降低的过程。
设备的中断服务程序在调用DevicePowerNotify函数前设置fBoostRequested和fReductionRequested标志。这是因为DevicePowerNotify调用可能导致调用IOCTL_POWER_SET而在同一线程中再次进入驱动程序。DeviceIoControl调用会清除标记,从而使驱动程序在之后能在后面对设备电源状态进行调整。
2、如何为设备驱动程序添加电源管理
驱动设计人员可以添加到一个设备驱动程序支持电源管理,以减少对目标设备的功耗。要做到这一点,驱动程序需导出流接口,如果已经实现了流接口,那么可以开始添加电源管理的支持。
硬件和软件的假定
·你掌握了如何从命令行创建一个Platform Builder 的WinCE运行时镜像。可查看Build Tool。跟踪你的进度如下表所示:
步骤
主题
1、创建一个流接口驱动
How to Create a Device Driver
2、为流接口驱动添加IO控制代码(IOCTLs).想了解更多电源管理信息。见
Power Management IOCTLs.
Power-Manageable Device Drivers
3、通知电源管理器,驱动程序支持电源管理。详见
Power Management Functions.
无
4、在你的驱动程序中实现设备电源状态。详见
Device Power States.
Power Management Implementation in Drivers
5、编译你的驱动程序,如果编译无错,那么你已经成功的为流接口驱动添加了电源管理。详见
Troubleshooting: Building a Driver.
Building a Device Driver from the Command Line
6、调试驱动程序
How to Debug a Device Driver
3、电源管理的设备驱动程序
为了创建一个能够识别目标设备电源状态的设备驱动,开发者必须首先创建一个能够通知非COM相关的设备接口的设备驱动,这个非COM相关的设备接口接着定义设备是电源管理的。
驱动程序开发者可以使用一下的方式通知一个设备接口:
·在注册表键的IClass值中定义这个接口,这个键值用于激活设备。
·定义在设备驱动的Init函数中使用Active注册键里的IClass值。
·使用ActivateDeviceEx函数的REGINI参数定义IClass值。
·在设备驱动程序中显示地调用AdvertiseInterface函数。
典型情况下,一旦一个驱动被通知为一个电源管理的驱动,驱动程序只需要处理来自电源管理器的DeviceIoControl调用。电源管理器使用IOCTL代码与设备进行通信,设备的电源管理I/O如下表所示:
设备管理的设备控制IOCTL
IOCTL
描述
IOCTL_POWER_CAPABILITIES
请求设备向电源管理器报告它支持哪些电源状态及他们特征是什么
IOCTL_POWER_SET
请求设备更新它的设备电源状态
IOCTL_POWER_QUERY
询问设备是否已经准备好进入一种新的设备电源状态
IOCTL_POWER_GET
请求设备向电源管理器报告它的当前设备电源状态
IOCTL_REGISTER_POWER_RELATIONSHIP
请求父设备注册它控制的所有设备
驱动开发者可以实现并使用可选的IOCTL_POWER_QUERY控制码,以便在驱动程序还没有准备好改变电源状态时延迟电源切换。驱动开发者可以通过修改MDD层来支持IOCTL_POWER_QUERY,虽然这样修改可能会导致MDD层与电源管理器的未来版本不兼容。
4、在驱动程序中实现电源设备电源状态
当将一个驱动程序配置为支持电源管理时,必须为这个驱动程序的每一个入口点确定电源状态值。如果开发这精确的定义了这些电源状态值,那么取决于目标设备的当前电源状态。驱动程序将以适当的方式工作。
需要注意的是在对XXX_PowerUp调用时,驱动程序并不一定是打开(Power up)目标设备,取而代之的是驱动程序必须将电源状态恢复到由电源管理器设置的值,这个值很可能是D3或者D4状态,而不是想象中的D0状态。同样,在对XXX_PowerDwon调用时,驱动程序并不一定是关闭(Power down)目标设备。 5、流接口驱动中电源管理的实现
在支持电源管理之前,必须先导出一个流接口。导出的流接口会提供一组流接口以便实现标准的I/O函数,这些函数会被Kernel使用。
关于导出流接口的更多信息,见
Stream Interface Driver Implementation.
除流接口函数外,驱动程序还必须支持IOCTL_POWER_CAPABILITIES和IOCTL_POWER_SET这两个IOCTL。
关于IOCTL_POWER_SET的更多信息,
IOCTL_POWER_SET, see
IOCTL_POWER_SETRequest Processing.
For more information about support for
IOCTL_POWER_CAPABILITIES,see
DevicePower Capabilities.
Once you have configured the stream interface, you canconfigure your driver to support power management. For more information, see
Power ManagementImplementation in Drivers.
6、设备类型名
从Windows CE4.10开始,支持电源管理的设备可分属于不同的设备类型。这些设备类型由于预定义类型和自定义类型组成,电源管理器的API接受设备名称,也可以接受有效的设备类名称。例如:下面的名称都是有效的设备名称:
· COM1:
· {A32942B7-920C-486b-B0E6-92A702A99B35}COM1:
· {98C5250D-C29A-4985-AE5F-AFE5367E5006}CISCO1
· {8DD679CE-8AB4-43c8-A14A-EA4963FAA715}DSK1:
如果某个设备的类型无效,那么此设备将被假定属于默认设备类型。例如,上面COM1:和{A32942B7-920C-486b-B0E6-92A702A99B35}/COM1:是等效的。
6、设备初始化
Duringinitialization, the device driver should put the device into D0, and reportdevice capabilities as accurately as possible when queried by the Power Managerthrough
IOCTL_POWER_CAPABILITIES.
即在初始化期间,设备驱动应该讲设备设置为D0,同时在电源管理器通过
IOCTL_POWER_CAPABILITIES时尽可能准确的汇报设备特性。
8、IOCTL_POWER_SET请求处理
调整电源管理设备的电源状态,使用的IOCTL_POWER_SET设备的IOCTL。实施支持此IOCTL时,设备驱动程序开发人员应该注意以下几点:
·设备并不一定支持所有五种设备电源状态,但至少支持D0状态;如果设备仅支持D0状态,则它也不需要处理IOCTL_POWER_SET。
·电源管理器可能会要求设备进入任何设备电源状态,而并不仅仅是设备声明支持的几个。
·如果一个设备被要求进入一个它并不支持的电源状态,它就会进入另一个它支持的更高功耗的状态。例如,一个设备并不支持D2,它会被要求进入D1。
·电源管理器可能会通过发出IOCTL_POWER_SET,使设备再次进入它已经处于的当前状态。这时,设备驱动程序简单的返回成功即可。
·由于应用程序需求的限制,设备的电源状态不一定与系统的电源状态同步。
9、挂起和恢复处理
电源管理的流设备驱动程序将通过XXX_PowerDown(设备管理器)和XXX_PowerUp(设备管理器)不断的接受系统挂起和恢复状态的通知。这些通知是在内核调用OEMPowerOff函数之前的中断处理中发出的。掉电/上电回调机制与电源管理无关,并允许原有的设备驱动程序下运行(Microsoft®Windows®CE .NET 4.0及以后偶的版本中适用)
驱动开发者必须知道在系统处于挂起状态时设备适合使用哪些电源状态,从而依此实现其驱动程序。然而,它可能未必适合于特定的设备,挂起系统电源状态配置或应用设备的电源要求。例如,一个音频设备可能需要留在D0多媒体应用的状态。如果音频芯片微处理器需要频繁设置DMA缓冲区,设备驱动程序开发人员可以使操作系统暂停状态时将音频设备处于D0状态。
如果驱动开发人员在挂起期间改变了设备的电源状态,就必须在系统恢复的同时恢复设备的电源状态。在系统挂起期间,这些设备应尽量保证其实际行为对电源管理器而言是透明的。
Power-manageablestream devices can automatically notify the Power Manager of their presencewhen they are loaded by
ActivateDeviceEx.If the GUID
"{A32942B7-920C-486b-B0E6-92A702A99B35}" is partof their
IClass value, which is a
REG_MULTI_SZ, the Power Managerwill receive a device notification when the device is loaded. The Power Managerrequests notifications for all classes listed in the
HKEY_LOCAL_MACHINECurrentControlSetControlPowerInterfacesregistry key.
Devices canmanage their own power by calling the
DevicePowerNotifyfunction when they receive the
IOCTL_POWER_CAPABILITIESI/O control. The Power Manager will recognize requests issued while the deviceis processing the IOCTL.
If an OEMchooses to implement a device API outside of the stream interface, the OEMneeds to customize the Power Manager to communicate using the new mechanism.
10、D3设备状态和系统唤醒
The D3 device state deserves specialconsideration because it has special semantics not strictly related to its powerconsumption level. Devices in the D3 state are allowed, but not required, toawaken the system from a suspend state.
The following guidelines help supportthe D3 state in device drivers:
· Devices that can wake the system from asuspend state should not request the D3 state through
DevicePowerNotify.This is because enabling a device as a wake source is not always appropriate,unless the system is going to enter a suspend state. The driver cannotdistinguish
IOCTL_POWER_SETrequests for D3 that it has initiated itself from those initiated by the PowerManager as part of a system power state transition.
· If desired, wake-enabled devices can define D2and D3 to be identical except for enabling wake functionality.
· Devices that cannot wake the system from asuspend state but that do have a lowest-power mode that can generate deviceactivity are allowed to use D3 in self-management of power.
· If a non-wake-enabled device is in D3 and thesystem suspends, it should transition to D4 in its
XXX_PowerDown(Device Manager) handler and back to D3 in its
XXX_PowerUp(Device Manager) handler. If it cannot do this, it should not attempt tosupport D3, but should transition to D4 when requested to go into D3.
· The above guidelines imply that devices thatsupport D3 are not guaranteed to be able to wake the system from a suspendstate.
However, OEMs designing system powerstates and application developers calling
SetPowerRequirementwill consider the D3 state as having special properties when the system as awhole suspends. The D3 guidelines outlined here enable OEMs and applicationdevelopers to request that any device go into D3 during a suspend state withoutconcern
for whether or not the device actually supports waking the system.
11、设备电源特性
IOCTL_POWER_CAPABILITIESqueries device-specific characteristics including latency, power consumption,system wake, and inrush, from the device driver during Plug and Playenumeration. The device driver also reports which device power states itsupports in its
response to this IOCTL. The Power Manager generally does notrequest that a device go into a power state that it does not support. However,a driver developer should not assume such requests will not occur. Because aWindows CE-based device manufacturer can customize
the Power Manager, thedevice manufacturer may choose to ignore the DeviceDx field of the
POWER_CAPABILITIESstructure.