支持单组件设备呈现单个或多个功能性电源状态

单组件设备的 KMDF 驱动程序可以为组件定义一个或多个功能电源状态,并注册电源管理框架 (PoFx) 在组件的 Fx 状态更改或其活动/空闲条件更改时调用的回调函数。 从 UMDF 版本 2.0 开始,单组件设备的 UMDF 驱动程序可以定义单个功能电源状态 (F0) 。

有关 PoFx 的详细信息,请参阅 Power Management Framework 概述

若要实现对单组件设备的 Fx 状态支持,必须在设备首次启动之前或期间按顺序执行以下操作。

  1. 此步骤仅适用于 KMDF 驱动程序。 调用 WdfDeviceWdmAssignPowerFrameworkSettings 以指定 WDF 在注册 PoFx 时使用的 power Framework 设置。 在驱动程序调用 WdfDeviceWdmAssignPowerFrameworkSettings 时提供的WDF_POWER_FRAMEWORK_SETTINGS结构中,驱动程序可以提供指向多个回调函数的指针。 如果驱动程序仅支持单个功能电源状态 (F0) ,则此步骤是可选的。

  2. 此步骤适用于 KMDF 驱动程序和 UMDF 驱动程序。 调用 WdfDeviceAssignS0IdleSettings 并将WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS结构的 IdleTimeoutType 字段设置为 SystemManagedIdleTimeoutSystemManagedIdleTimeoutWithHint。 这样做会导致 WDF 注册到 PoFx。

    对于 KMDF 驱动程序,在注册到 PoFx 时,框架使用驱动程序在调用 WdfDeviceWdmAssignPowerFrameworkSettingsWDF_POWER_FRAMEWORK_SETTINGS提供的信息。

由于设备可以多次启动(例如,在资源重新均衡的情况下),因此驱动程序可能会在 EvtDeviceSelfManagedIoInit 回调函数中执行上述步骤。 如果驱动程序已注册 EvtDeviceSelfManagedIoInit 回调函数,则框架在框架首次调用驱动程序的 EvtDeviceD0Entry 回调函数后,为每个设备调用一次该回调函数。

本主题中的其余信息仅适用于 KMDF 驱动程序。

通电

当驱动程序调用 WdfDeviceWdmAssignPowerFrameworkSettings 时,它可以提供指向 EvtDeviceWdmPostPoFxRegisterDevice 回调函数的指针。

框架在向 PoFx 注册后调用驱动程序的 EvtDeviceWdmPostPoFxRegisterDevice 回调函数。 下面是典型启动序列的示例:

  1. EvtDevicePrepareHardware
  2. EvtDeviceD0Entry (PrevState = WdfPowerDeviceD3Final)
  3. EvtInterruptEnable
  4. EvtDeviceWdmPostPoFxRegisterDevice // PoFx 句柄可用

驱动程序提供 EvtDeviceWdmPostPoFxRegisterDevice 回调,如果它必须使用 POHANDLE 执行任何其他操作进行 Power Framework 注册。 例如,它可以指定延迟、驻留和唤醒要求。 有关使用 POHANDLE 的例程的详细信息,请参阅 设备电源管理例程

驱动程序还可以使用 POHANDLE 与 PoFx 交换电源控制请求:

关机

WDF 在删除 PoFx 的指定注册之前,调用 EvtDeviceWdmPrePoFxUnregisterDevice 回调函数。

驱动程序可以在它提供给 WdfDeviceWdmAssignPowerFrameworkSettingsWDF_POWER_FRAMEWORK_SETTINGS 结构中提供指向 ComponentIdleStateCallback 例程的指针。 PoFx 调用此例程以通知驱动程序指定组件的 Fx 电源状态的挂起更改。 在此回调例程中,驱动程序可以执行与功能状态更改相关的特定于硬件的操作。

例如,在将组件转换为低功耗 Fx 状态之前,驱动程序可能会保存硬件状态并禁用中断和 DMA。 驱动程序调用 WdfInterruptReportInactive 以通知系统中断不再处于活动状态。 在 F 状态转换期间关闭中断可能会降低系统整体功耗。

驱动程序还可以在其WDF_POWER_FRAMEWORK_SETTINGS结构中提供指向 ComponentIdleConditionCallback 例程的指针。 PoFx 调用此例程以通知驱动程序组件已变为空闲状态。 在此例程中,驱动程序开始停止其电源管理的队列和自我管理的 I/O 操作:

  1. 为每个设备的电源托管队列调用 一次 WdfIoQueueStop 。 在每次调用 WdfIoQueueStop 时,提供 EvtIoQueueState 回调。 通常,驱动程序从 ComponentIdleConditionCallback 中调用 WdfIoQueueStop

  2. 确保从每个电源托管队列中调度到驱动程序的请求快速完成。 根据驱动程序,这可能涉及以下部分或全部内容:

    • 如果驱动程序长时间未保留请求,并且未将其转发到这样做的 I/O 目标,请继续执行步骤 3。
    • 如果驱动程序长时间保留某些请求,请将这些请求重新排队到手动队列。 然后,在其 ComponentActiveConditionCallback 例程中,驱动程序可以检索请求。
    • 如果驱动程序将某些请求转发到长时间保留这些请求的 I/O 目标,请取消这些请求。 重新提交 ComponentActiveConditionCallback 中的请求。
  3. 每个队列停止后,框架将调用 EvtIoQueueState。 如果驱动程序正在停止多个电源管理的队列,框架会多次调用 EvtIoQueueState ,每个队列调用一次。

    驱动程序必须在调用最后一个 EvtIoQueueState 函数后调用 PoFxCompleteIdleCondition。 例如,驱动程序可以从最后一个 EvtIoQueueState 内部进行此调用。

    为了确定哪个调用是最后一次,驱动程序可以使用计数器来跟踪框架调用 EvtIoQueueState 的次数。 Singlecomp 示例演示了此方法。 此示例从 WDK Windows 8开始提供。

下面是典型关机序列的示例:

  1. ComponentIdleConditionCallback
  2. ComponentIdleStateCallback
  3. EvtInterruptDisable
  4. EvtDeviceD0Exit

ComponentActiveConditionCallback 中重启电源管理的队列和自我管理的 I/O 操作。

如果驱动程序以前名为 WdfInterruptReportInactive,则通过从 ComponentActiveConditionCallbackComponentIdleStateCallback 调用 WdfInterruptReportActive 重新启用非活动中断。