Arbeiten mit USB-Rohren

Das Framework stellt jede Pipe in einer USB-Schnittstelle als FRAMEWORK-USB-Pipeobjekt dar. Wenn ein Treiber ein USB-Gerät konfiguriert, erstellt das Framework ein Framework-USB-Pipeobjekt für jede Pipe in jeder ausgewählten Schnittstelle. Pipeobjektmethoden ermöglichen es einem Treiber, die folgenden Vorgänge auszuführen:

Abrufen von Pipeinformationen

Nachdem Sie WdfUsbInterfaceGetConfiguredPipe aufgerufen haben , um ein Handle für ein Framework-USB-Pipeobjekt abzurufen, kann Ihr Treiber die folgenden Methoden aufrufen, die das USB-Pipeobjekt definiert, um Informationen über die USB-Pipe abzurufen:

WdfUsbTargetPipeGetIoTarget
Gibt ein Handle an das E/A-Zielobjekt zurück, das einer USB-Pipe zugeordnet ist. Der Treiber kann dieses Handle an WdfRequestSend übergeben.

WdfUsbTargetPipeGetInformation
Ruft Informationen zu einer USB-Pipe und ihrem Endpunkt ab.

WdfUsbTargetPipeGetType
Gibt den Typ einer USB-Pipe zurück.

WdfUsbTargetPipeIsInEndpoint
Bestimmt, ob eine USB-Pipe mit einem Eingabeendpunkt verbunden ist.

WdfUsbTargetPipeIsOutEndpoint
Bestimmt, ob eine USB-Pipe mit einem Ausgabeendpunkt verbunden ist.

WDF_USB_PIPE_DIRECTION_IN
Bestimmt, ob ein USB-Endpunkt ein Eingabeendpunkt ist.

WDF_USB_PIPE_DIRECTION_OUT
Bestimmt, ob ein USB-Endpunkt ein Ausgabeendpunkt ist.

Weitere Informationen finden Sie unter Auflisten von USB-Rohren.

Lesen aus einer Pipe

Um Daten aus einer USB-Eingabepipe zu lesen, kann Ihr Treiber eine beliebige (oder alle) der folgenden drei Techniken verwenden:

  • Synchrones Lesen von Daten

    Um Daten synchron aus einer USB-Eingabepipe zu lesen, kann Ihr Treiber die WdfUsbTargetPipeReadSynchronously-Methode aufrufen. Diese Methode erstellt und sendet eine Leseanforderung, die nach Abschluss des E/A-Vorgangs zurückgegeben wird.

  • Asynchrones Lesen von Daten

    Um Daten asynchron aus einer USB-Eingabepipe zu lesen, kann Ihr Treiber die WdfUsbTargetPipeFormatRequestForRead-Methode aufrufen, um eine Leseanforderung zu erstellen. Anschließend kann der Treiber WdfRequestSend aufrufen, um die Anforderung asynchron (oder synchron) zu senden.

  • Asynchrones und kontinuierliches Lesen von Daten

    Ein fortlaufender Reader ist ein vom Framework bereitgestellter Mechanismus, um sicherzustellen, dass eine Leseanforderung für eine USB-Pipe immer verfügbar ist. Mit diesem Mechanismus wird sichergestellt, dass der Treiber immer bereit ist, Daten von einem Gerät zu empfangen, das einen asynchronen, nicht angeforderten Eingabedatenstrom bereitstellt. Beispielsweise kann ein Treiber für eine Netzwerkschnittstellenkarte (NIC) einen fortlaufenden Reader verwenden, um Eingabedaten zu empfangen.

    Um einen fortlaufenden Reader für eine Eingabepipe zu konfigurieren, muss die Rückruffunktion EvtDevicePrepareHardware des Treibers die WdfUsbTargetPipeConfigContinuousReader-Methode aufrufen. Mit dieser Methode wird eine Reihe von Leseanforderungen an das E/A-Ziel des Geräts in die Warteschlange gestellt.

    Außerdem muss die EvtDeviceD0Entry-Rückruffunktion des Treibers WdfIoTargetStart aufrufen, um den fortlaufenden Reader zu starten, und die EvtDeviceD0Exit-Rückruffunktion des Treibers muss WdfIoTargetStop aufrufen, um den fortlaufenden Reader zu beenden.

    Jedes Mal, wenn diese Daten vom Gerät verfügbar sind, führt das E/A-Ziel eine Leseanforderung aus, und das Framework ruft eine von zwei Rückruffunktionen auf: EvtUsbTargetPipeReadComplete, wenn das E/A-Ziel die Daten erfolgreich liest, oder EvtUsbTargetPipeReadersFailed, wenn das E/A-Ziel einen Fehler meldet.

    Wenn Sie den optionalen EvtUsbTargetPipeReadersFailed-Rückruf nicht bereitstellen, reagiert das Framework auf einen fehlgeschlagenen Leseversuch, indem es eine weitere Leseanforderung sendet. Wenn sich der Bus also in einem Zustand befindet, in dem er keine Lesevorgänge akzeptiert, sendet das Framework ständig neue Anforderungen zur Wiederherstellung nach einem fehlgeschlagenen Lesevorgang.

    Nachdem ein Treiber WdfUsbTargetPipeConfigContinuousReader aufgerufen hat, kann der Treiber WdfUsbTargetPipeReadSynchronously oder WdfRequestSend nicht verwenden, um E/A-Anforderungen an die Pipe zu senden, es sei denn, die Rückruffunktion EvtUsbTargetPipeReadersFailed des Treibers wird aufgerufen und gibt FALSE zurück.

Standardmäßig meldet das Framework einen Fehler, wenn Ihr Treiber einen Lesepuffer angibt, der kein Vielfaches der maximalen Paketgröße der Pipe ist. Ihr Treiber kann WdfUsbTargetPipeSetNoMaximumPacketSizeCheck aufrufen, um diesen Test der Lesepuffergrößen zu deaktivieren.

Verwandte Informationen

Schreiben in eine Pipe

Um Daten in eine USB-Ausgabepipe zu schreiben, kann Ihr Treiber eine (oder beide) der folgenden Techniken verwenden:

  • Synchrones Schreiben von Daten

    Um Daten synchron in eine USB-Ausgabepipe zu schreiben, kann Ihr Treiber die WdfUsbTargetPipeWriteSynchronously-Methode aufrufen. Diese Methode erstellt und sendet eine Schreibanforderung, die nach Abschluss des E/A-Vorgangs zurückgegeben wird.

  • asynchrones Schreiben von Daten

    Um Daten asynchron in eine USB-Eingabepipe zu schreiben, kann Ihr Treiber die WdfUsbTargetPipeFormatRequestForWrite-Methode aufrufen, um eine Schreibanforderung zu erstellen. Anschließend kann der Treiber WdfRequestSend aufrufen, um die Anforderung asynchron zu senden.

Weitere Informationen finden Sie unter Senden von USB-Massenübertragungsanforderungen.

Beenden und Zurücksetzen einer Pipe

Ihr Treiber kann die folgenden Methoden aufrufen, um eine USB-Pipe zu beenden oder zurückzusetzen:

WdfUsbTargetPipeAbortSynchronously
Sendet synchron eine Anforderung zum Beenden einer USB-Pipe.

WdfUsbTargetPipeFormatRequestForAbort
Formatiert eine Anforderung zum Beenden einer USB-Pipe. Der Treiber kann WdfRequestSend aufrufen, um die Anforderung synchron oder asynchron zu senden.

WdfUsbTargetPipeResetSynchronously
Sendet synchron eine Anforderung zum Zurücksetzen einer USB-Pipe.

WdfUsbTargetPipeFormatRequestForReset
Formatiert eine Anforderung zum Zurücksetzen einer USB-Pipe. Der Treiber muss WdfRequestSend aufrufen, um die Anforderung synchron oder asynchron zu senden.

Wenn das USB-Ziel Ihres Treibers eine E/A-Anforderung mit einem Fehlerstatuswert abschließt , sollte Ihr Treiber die folgenden Schritte ausführen:

  1. Beenden Sie die Pipe, und brechen Sie alle zusätzlichen E/A-Anforderungen ab, die der Treiber an das USB-Ziel gesendet hat, wenn das Ziel die Anforderungen nicht abgeschlossen hat.

    Rufen Sie WdfIoTargetStop auf, wobei das WdfIoTargetCancelSentIo-Flag festgelegt ist.

  2. Synchrones Senden einer Abbruchanforderung an die Pipe.

    Rufen Sie WdfUsbTargetPipeAbortSynchronously auf, oder rufen Sie WdfUsbTargetPipeFormatRequestForAbort gefolgt von WdfRequestSend auf, wobei das flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS festgelegt ist.

  3. Synchrones Senden einer Zurücksetzungsanforderung an die Pipe.

    Rufen Sie WdfUsbTargetPipeResetSynchronously auf, oder rufen Sie WdfUsbTargetPipeFormatRequestForReset gefolgt von WdfRequestSend auf, wobei das flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS festgelegt ist.

  4. Starten Sie die Pipe neu.

    Rufen Sie WdfIoTargetStart auf.

  5. Senden Sie die E/A-Anforderung, bei der ein Fehler aufgetreten ist, und alle E/A-Anforderungen, die auf die fehlgeschlagene Anforderung folgten, erneut.

Nach einer erheblichen Anzahl von mehreren Fehlern sollte der Treiber versuchen, den USB-Anschluss wie folgt zurückzusetzen:

  1. Beenden Sie alle aktiven Pipes, und brechen Sie alle zusätzlichen E/A-Anforderungen ab, die der Treiber an das USB-Ziel der einzelnen Pipe gesendet hat, wenn das Ziel sie nicht abgeschlossen hat.

    Rufen Sie für jede aktive Pipe WdfIoTargetStop mit dem WdfIoTargetCancelSentIo-Flagsatz auf.

  2. Senden Sie synchron eine Anforderung zum Zurücksetzen des USB-Ports.

    Rufen Sie WdfUsbTargetDeviceResetPortSynchronously auf.

  3. Starten Sie die Pipes neu.

    Rufen Sie WdfIoTargetStart für jede Pipe auf, die der Treiber beendet hat.

  4. Senden Sie die letzte E/A-Anforderung, bei der ein Fehler aufgetreten ist, und alle E/A-Anforderungen, die auf die fehlgeschlagene Anforderung folgten, erneut.

Verwandte Informationen finden Sie unter Wiederherstellen von USB-Pipefehlern.

Senden einer URB an eine Pipe

Wenn Ihr KMDF-Treiber mit einer USB-Pipe kommuniziert, indem E/A-Anforderungen gesendet werden, die URBs enthalten, kann der Treiber die folgenden Methoden aufrufen:

WdfUsbTargetPipeSendUrbSynchronously (nur KMDF)
Sendet synchron eine E/A-Anforderung, die eine URB enthält.

WdfUsbTargetPipeFormatRequestForUrb (nur KMDF)
Formatiert eine E/A-Anforderung, die eine URB enthält. Der Treiber kann WdfRequestSend aufrufen, um die Anforderung synchron oder asynchron zu senden.

WdfUsbTargetPipeWdmGetPipeHandle (nur KMDF)
Gibt den USBD-Pipehandle eines Geräts zurück. Für einige URBs ist dieses Handle erforderlich.