Verwenden eines Interrupts zum Reaktivieren eines Geräts

Wenn ein Gerät in einen Zustand mit geringer Energieleistung überwechselt, trennt das Framework Unterbrechungen (oder meldet sie als inaktiv), die für die E/A-Behandlung verwendet werden. Ab KMDF 1.13 und UMDF 2.0, die auf Windows 8.1 ausgeführt werden, kann ein WDF-Treiber ein Framework-Interruptobjekt erstellen, das aktiv bleibt, wenn das Gerät in einen Zustand mit geringer Leistung übergeht, und dann verwendet werden kann, um das Gerät zu wecken und den vollständigen D0-Zustand wiederherzustellen.

Wenn Sie einen WDF-Treiber für eine SoC-Plattform (System on a Chip) entwickeln, können Sie einen solchen Interrupt verwenden, um ein Gerät zu wecken, das keinen herkömmlichen Aktivierungssignalmechanismus bietet. Um diese Funktionalität verwenden zu können, muss das Gerät über Hardwareunterstützung für Aktivierungsunterbrechungen verfügen, die über ACPI verfügbar gemacht werden. Der Treiber, der den Interrupt erstellt, muss der Besitzer der Energierichtlinie des Geräts sein.

Wenn das Gerät in einen Energiesparzustand wechselt, trennt das Framework keinen Interrupt, der als Aktivierungsfähig identifiziert wurde. Wenn das Gerät unterbricht, ruft das Framework die Rückrufroutinen EvtDeviceD0Entry und EvtInterruptIsr des Treibers unter IRQL = PASSIVE_LEVEL auf.

Wenn Ihr Treiber bereits ein Interruptobjekt auf passiver Ebene für die E/A-Verarbeitung erstellt, wird empfohlen, dasselbe Interruptobjekt für die Aktivierungsfunktion freizusetzen. In diesem Szenario implementiert die EvtInterruptIsr-Rückrufroutine des Treibers bedingte Logik, um die Behandlung für E/A-bezogene Interrupts sowie die Wake-Behandlung durchzuführen.

Wenn Ihr Treiber jedoch einen Interrupt verwendet, der am IRQL (DIRQL) des Geräts verarbeitet werden muss, wird empfohlen, ein zusätzliches Framework-Interruptobjekt zu erstellen, um Die Aktivierungsfunktion bereitzustellen.

Führen Sie die folgenden Schritte aus, um ein Wake-fähiges Interruptobjekt in Ihrem KMDF- oder UMDF-Treiber zu erstellen:

  1. Rufen Sie WdfDeviceAssignS0IdleSettings auf, in der Regel von EvtDriverDeviceAdd, und geben Sie IdleCanWakeFromS0 im IdleCaps-Parameter an .

  2. Rufen Sie optional WdfDeviceInitSetPowerPolicyEventCallbacks auf , um Ereignisrückruffunktionen zu registrieren, die unter Unterstützen der Systemreaktivierung beschrieben sind.

  3. Rufen Sie WDF_INTERRUPT_CONFIG_INIT auf, um eine WDF_INTERRUPT_CONFIG-Struktur zu initialisieren. Stellen Sie eine EvtInterruptIsr-Rückruffunktion bereit, die auf passiver Ebene aufgerufen werden soll. Legen Sie in der Konfigurationsstruktur PassiveHandling und CanWakeDevice auf TRUE fest. Rufen Sie dann WdfInterruptCreate über die EvtDevicePrepareHardware-Rückruffunktion Ihres Treibers auf, um das Framework-Interruptobjekt zu erstellen.

  4. Rufen Sie WdfDeviceAssignSxWakeSettings auf, um das Gerät so zu konfigurieren, dass das System aus einem Energiesparzustand reaktiviert wird.

    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. Wenn das Gerät in einen Energiesparzustand wechselt, ruft das Framework EvtInterruptDisable nicht für den Wake-fähigen Interrupt auf. Das Framework ruft EvtDeviceArmWakeFromS0 auf, wenn der Treiber eine bereitgestellt hat.

  6. Wenn das Gerät den Aktivierungs-Interrupt signalisiert, ruft das Framework die EvtDeviceD0Entry-Rückrufroutine des Treibers auf.

  7. Wenn der EvtDeviceD0Entry-Rückruf des Treibers erfolgreich ist, ruft das Framework den EvtInterruptIsr-Rückruf des Treibers auf passiver Ebene auf. Bevor der Interrupthandler zurückgibt, muss er den Interrupt im Interruptcontroller zum Schweigen bringen. Wenn der Treiber einen Fehlercode von EvtDeviceD0Entry zurückgibt, trennt das Framework den Interrupt und ruft den EvtInterruptDisable-Rückruf des Treibers auf, sofern der Treiber einen bereitgestellt hat.

  8. Das Framework ruft die folgenden Rückrufroutinen für Reaktivierungsereignisse auf, wenn der Treiber eine bereitgestellt hat:

  9. Das Framework fährt mit der normalen Power-up-Rückrufsequenz fort, wie unter Power-Up-Sequenz für eine Funktion oder einen Filtertreiber beschrieben.

Sie können die Debuggererweiterung !wdfkd.wdfinterrupt verwenden, um anzuzeigen, ob ein bestimmter Interrupt für die Aktivierungsfähig konfiguriert wurde.

Die Aktivierungsunterbrechungsfunktion kann nicht in Verbindung mit dem selektiven ANHALTEN von USB verwendet werden.