使用中断来唤醒设备

当设备转换为低功耗状态时,框架会断开连接 (或报告为非活动) 用于 I/O 处理的中断。 从在 Windows 8.1 上运行的 KMDF 1.13 和 UMDF 2.0 开始,WDF 驱动程序可以创建一个框架中断对象,该对象在设备转换为低功耗状态时保持活动状态,然后可用于唤醒设备并将其还原到完全处于 D0 状态。

如果要为片上系统开发 WDF 驱动程序 (SoC) 平台,则可以使用此类中断唤醒不提供传统唤醒信号机制的设备。 若要使用此功能,设备必须具有通过 ACPI 公开的唤醒中断的硬件支持。 创建中断的驱动程序必须是设备的电源策略所有者。

当设备转换为低功耗状态时,框架不会断开已标识为支持唤醒的中断。 当设备中断时,框架在 IRQL = PASSIVE_LEVEL调用驱动程序的 EvtDeviceD0EntryEvtInterruptIsr 回调例程。

如果驱动程序已创建被动 级中断对象 用于 I/O 处理,我们建议共享同一个中断对象以用于唤醒功能。 在此方案中,驱动程序的 EvtInterruptIsr 回调例程实现条件逻辑以执行 I/O 相关中断的处理以及唤醒处理。

但是,如果驱动程序使用的中断需要在设备的 IRQL (DIRQL) 进行处理,我们建议创建额外的框架中断对象以提供唤醒功能。

按照以下步骤在 KMDF 或 UMDF 驱动程序中创建支持唤醒的中断对象:

  1. 调用 WdfDeviceAssignS0IdleSettings(通常来自 EvtDriverDeviceAdd),并在 IdleCaps 参数中指定 IdleCanWakeFromS0

  2. (可选)调用 WdfDeviceInitSetPowerPolicyEventCallbacks 以注册 支持系统唤醒中所述的事件回调函数。

  3. 调用 WDF_INTERRUPT_CONFIG_INIT 以初始化 WDF_INTERRUPT_CONFIG 结构。 提供在被动级别调用的 EvtInterruptIsr 回调函数。 在配置结构中,将 PassiveHandlingCanWakeDevice 设置为 TRUE。 然后从驱动程序的 EvtDevicePrepareHardware 回调函数调用 WdfInterruptCreate 以创建框架中断对象。

  4. 调用 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;
    }
    
  5. 当设备转换为低功耗状态时,框架不会为支持唤醒的中断调用 EvtInterruptDisable 。 如果驱动程序提供了 EvtDeviceArmWakeFromS0 ,框架会调用该框架。

  6. 当设备发出唤醒中断信号时,框架会调用驱动程序的 EvtDeviceD0Entry 回调例程。

  7. 如果驱动程序的 EvtDeviceD0Entry 回调返回成功,框架将在被动级别调用驱动程序的 EvtInterruptIsr 回调。 在中断处理程序返回之前,它必须在中断控制器中静音中断。 如果驱动程序从 EvtDeviceD0Entry 返回失败代码,框架将断开中断,并调用驱动程序的 EvtInterruptDisable 回调(如果驱动程序已提供)。

  8. 如果驱动程序提供了以下唤醒事件回调例程,则框架会调用以下唤醒事件回调例程:

  9. 框架继续执行正常的通电回调序列,如 函数或筛选器驱动程序的启动序列中所述。

可以使用 !wdfkd.wdfinterrupt 调试器扩展来显示特定中断是否已配置为支持唤醒。

唤醒中断功能不能与 USB 选择性挂起结合使用。