使用中断来唤醒设备
当设备转换为低功耗状态时,框架会断开连接 (或报告为非活动) 用于 I/O 处理的中断。 从在 Windows 8.1 上运行的 KMDF 1.13 和 UMDF 2.0 开始,WDF 驱动程序可以创建一个框架中断对象,该对象在设备转换为低功耗状态时保持活动状态,然后可用于唤醒设备并将其还原到完全处于 D0 状态。
如果要为片上系统开发 WDF 驱动程序 (SoC) 平台,则可以使用此类中断唤醒不提供传统唤醒信号机制的设备。 若要使用此功能,设备必须具有通过 ACPI 公开的唤醒中断的硬件支持。 创建中断的驱动程序必须是设备的电源策略所有者。
当设备转换为低功耗状态时,框架不会断开已标识为支持唤醒的中断。 当设备中断时,框架在 IRQL = PASSIVE_LEVEL调用驱动程序的 EvtDeviceD0Entry 和 EvtInterruptIsr 回调例程。
如果驱动程序已创建被动 级中断对象 用于 I/O 处理,我们建议共享同一个中断对象以用于唤醒功能。 在此方案中,驱动程序的 EvtInterruptIsr 回调例程实现条件逻辑以执行 I/O 相关中断的处理以及唤醒处理。
但是,如果驱动程序使用的中断需要在设备的 IRQL (DIRQL) 进行处理,我们建议创建额外的框架中断对象以提供唤醒功能。
按照以下步骤在 KMDF 或 UMDF 驱动程序中创建支持唤醒的中断对象:
调用 WdfDeviceAssignS0IdleSettings(通常来自 EvtDriverDeviceAdd),并在 IdleCaps 参数中指定 IdleCanWakeFromS0。
(可选)调用 WdfDeviceInitSetPowerPolicyEventCallbacks 以注册 支持系统唤醒中所述的事件回调函数。
调用 WDF_INTERRUPT_CONFIG_INIT 以初始化 WDF_INTERRUPT_CONFIG 结构。 提供在被动级别调用的 EvtInterruptIsr 回调函数。 在配置结构中,将 PassiveHandling 和 CanWakeDevice 设置为 TRUE。 然后从驱动程序的 EvtDevicePrepareHardware 回调函数调用 WdfInterruptCreate 以创建框架中断对象。
调用 WdfDeviceAssignSxWakeSettings 将设备配置为将系统从低功耗状态唤醒。
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings); wakeSettings.DxState = PowerDeviceD3; wakeSettings.UserControlOfWakeSettings = WakeDoNotAllowUserControl; wakeSettings.Enabled = WdfTrue; status = WdfDeviceAssignSxWakeSettings(Device, &wakeSettings); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR,"WdfDeviceAssignSxWakeSettings failed %x\n", status); return status; }
当设备转换为低功耗状态时,框架不会为支持唤醒的中断调用 EvtInterruptDisable 。 如果驱动程序提供了 EvtDeviceArmWakeFromS0 ,框架会调用该框架。
当设备发出唤醒中断信号时,框架会调用驱动程序的 EvtDeviceD0Entry 回调例程。
如果驱动程序的 EvtDeviceD0Entry 回调返回成功,框架将在被动级别调用驱动程序的 EvtInterruptIsr 回调。 在中断处理程序返回之前,它必须在中断控制器中静音中断。 如果驱动程序从 EvtDeviceD0Entry 返回失败代码,框架将断开中断,并调用驱动程序的 EvtInterruptDisable 回调(如果驱动程序已提供)。
如果驱动程序提供了以下唤醒事件回调例程,则框架会调用以下唤醒事件回调例程:
框架继续执行正常的通电回调序列,如 函数或筛选器驱动程序的启动序列中所述。
可以使用 !wdfkd.wdfinterrupt 调试器扩展来显示特定中断是否已配置为支持唤醒。
唤醒中断功能不能与 USB 选择性挂起结合使用。