Arbeiten mit USB-Rohren

Das Framework stellt jede Pipe in einer USB-Schnittstelle als Framework-USB-Pipe-Objekt dar. Wenn ein Treiber ein USB-Gerät konfiguriert, erstellt das Framework ein Framework-USB-Pipe-Objekt 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-Pipe-Objekt abzurufen, kann Ihr Treiber die folgenden Methoden aufrufen, die das USB-Pipe-Objekt zum Abrufen von Informationen über die USB-Pipe definiert:

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.

Verwandte 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.

  • Daten asynchron lesen

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

  • Daten asynchron und kontinuierlich lesen

    Ein fortlaufender Reader ist ein vom Framework bereitgestellter Mechanismus, um sicherzustellen, dass eine Leseanforderung für eine USB-Pipe immer verfügbar ist. Dieser Mechanismus garantiert, 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 Netzwerkschnittstelle Karte (NIC) einen kontinuierlichen Reader verwenden, um Eingabedaten zu empfangen.

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

    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 kontinuierlich neue Anforderungen, um nach einem fehlerhaften Lesevorgang wiederherzustellen.

    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 EvtUsbTargetPipeReadersFailed-Rückruffunktion 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:

  • Daten synchron schreiben

    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. Dann kann der Treiber WdfRequestSend aufrufen, um die Anforderung asynchron zu senden.

Verwandte 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:

WdfUsbTargetPipeAbortSynchronous
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.

WdfUsbTargetPipeResetSynchronly
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 Fehler status Wert 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 mit festgelegtem WdfIoTargetCancelSentIo-Flag auf.

  2. Senden Sie synchron eine Abbruchanforderung an die Pipe.

    Rufen Sie WdfUsbTargetPipeAbortSynchronously auf, oder rufen Sie WdfUsbTargetPipeFormatRequestForAbort gefolgt von WdfRequestSend mit dem WDF_REQUEST_SEND_OPTION_SYNCHRONOUS-Flag auf.

  3. Senden Sie synchron eine Zurücksetzungsanforderung an die Pipe.

    Rufen Sie WdfUsbTargetPipeResetSynchronously auf, oder rufen Sie WdfUsbTargetPipeFormatRequestForReset gefolgt von WdfRequestSend mit dem WDF_REQUEST_SEND_OPTION_SYNCHRONOUS-Flag auf.

  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 mehrerer Fehler 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 auf, wobei das WdfIoTargetCancelSentIo-Flag festgelegt ist.

  2. Synchrones Senden einer Anforderung zum Zurücksetzen des USB-Anschlusses.

    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.

Weitere Informationen finden Sie unter Wiederherstellen nach 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. Einige URBs erfordern dieses Handle.