Использование прерывания для пробуждения устройства
Когда устройство переходит в состояние с низким энергопотреблением, платформа отключает (или сообщает о неактивных) прерываниях, которые используются для обработки операций ввода-вывода. Начиная с KMDF 1.13 и UMDF 2.0, работающих на Windows 8.1, драйвер WDF может создать объект прерывания платформы, который остается активным при переходе устройства в маломощное состояние, а затем может использоваться для пробуждения устройства и восстановления его полностью в состоянии D0.
Если вы разрабатываете драйвер WDF для платформы System on a Chip (SoC), вы можете использовать такое прерывание для пробуждения устройства, которое не предоставляет традиционный механизм сигнализации о пробуждении. Чтобы использовать эту функцию, устройство должно иметь аппаратную поддержку прерываний пробуждения, предоставляемых через ACPI. Драйвер, создающий прерывание, должен быть владельцем политики питания устройства.
Когда устройство переходит в состояние с низким энергопотреблением, платформа не отключает прерывание, которое было определено как поддерживающее пробуждение. Когда устройство прерывается, платформа вызывает процедуры обратного вызова EvtDeviceD0Entry драйвера и EvtInterruptIsr в IRQL = PASSIVE_LEVEL.
Если драйвер уже создает объект прерывания пассивного уровня для обработки ввода-вывода , рекомендуется совместно использовать этот объект прерывания для функции пробуждения. В этом сценарии подпрограмма обратного вызова EvtInterruptIsr драйвера реализует условную логику для обработки прерываний ввода-вывода, а также обработки пробуждения.
Однако если драйвер использует прерывание, требующее обработки в IRQL устройства (DIRQL), рекомендуется создать дополнительный объект прерывания платформы, чтобы обеспечить функцию пробуждения.
Выполните следующие действия, чтобы создать объект прерывания с поддержкой пробуждения в драйвере KMDF или UMDF.
Вызовите WdfDeviceAssignS0IdleSettings, как правило, из EvtDriverDeviceAdd, указав IdleCanWakeFromS0 в параметре IdleCaps .
При необходимости вызовите WdfDeviceInitSetPowerPolicyEventCallbacks , чтобы зарегистрировать функции обратного вызова событий, описанные в разделе Поддержка пробуждения системы.
Вызовите WDF_INTERRUPT_CONFIG_INIT для инициализации структуры WDF_INTERRUPT_CONFIG. Предоставьте функцию обратного вызова EvtInterruptIsr для вызова на пассивном уровне. В структуре конфигурации задайте для параметра PassiveHandling и CanWakeDevice значение TRUE. Затем вызовите WdfInterruptCreate из функции обратного вызова EvtDevicePrepareHardware драйвера, чтобы создать объект прерывания платформы.
Вызовите 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.