So senden Sie eine USB-Steuerungsübertragung (UWP-App)
Dieser Artikel demonstriert Folgendes:
- So formatieren Sie ein USB-Einrichtungspaket
- So initiieren Sie eine USB-Steuerungsübertragung von Ihrer App aus
Wichtige APIs
Eine App, die mit einem USB-Gerät kommuniziert, sendet in der Regel mehrere Steuerungsübertragungsanforderungen. Diese Anforderungen erhalten Informationen über das Gerät und senden Steuerungsbefehle, die vom Hardwareanbieter definiert sind. In diesem Thema erfahren Sie mehr über Steuerungsübertragungen und wie Sie sie in Ihrer UWP-App formatieren und versenden.
Eine Steuerungsübertragung kann Konfigurationsinformationen lesen oder schreiben oder gerätespezifische Funktionen ausführen, die vom Hardwareanbieter definiert sind. Wenn die Übertragung einen Schreibvorgang ausführt, handelt es sich um eine OUT-Übertragung; bei einem Lesevorgang handelt es sich um eine IN-Übertragung. Unabhängig von der Richtung erstellt eine Software, z. B. Ihre UWP-App, immer auf dem Hostsystem eine Anforderung für eine Steuerungsübertragung und initiiert diese. Unter Umständen kann Ihre App Steuerungsübertragungen initiieren, welche Daten lesen oder schreiben. In diesem Fall müssen Sie möglicherweise einen zusätzlichen Puffer senden.
Um alle Arten von Steuerungsübertragungen zu unterstützen, stellt Windows.Devices.Usb die folgenden Methoden bereit:
- SendControlOutTransferAsync (UsbSetupPacket)
- SendControlInTransferAsync (UsbSetupPacket)
- SendControlOutTransferAsync (UsbSetupPacket, IBuffer)
- SendControlInTransferAsync (UsbSetupPacket, IBuffer)
USB-Steuerübertragungen werden auch verwendet, um Deskriptordaten abzurufen oder Standardbefehle zu senden. Es wird jedoch empfohlen, diese Arten von Anforderungen zu senden, indem Sie bestimmte Methoden aufrufen, die von Windows.Devices.Usb bereitgestellt werden, anstatt eine Steuerungsübertragung manuell zu erstellen. Um beispielsweise eine alternative Einstellung auszuwählen, rufen Sie SelectSettingAsync auf, anstatt SendControlOutTransferAsync (UsbSetupPacket) aufzurufen.
Steuerungsübertragungen für bestimmte Typen von Standardanforderungen werden nicht unterstützt. Wenn Ihr Gerät jedoch zu einer Geräteklasse gehört, die von Windows.Devices.Usb unterstützt wird, können Sie einige Anforderungen gemäß der Spezifikation der Geräteklasse senden.
Vor der Installation
- Sie müssen dafür das Gerät geöffnet und das UsbDevice-Objekt abgerufen haben. Lesen Sie Wie man eine Verbindung zu einem USB-Gerät herstellt (UWP-App).
- Abrufen von Informationen zu vom Anbieter definierten Steuerelementbefehlen. Diese Befehle werden in der Regel in der Hardwarespezifikation definiert.
- Den vollständigen Code, der in diesem Thema gezeigt wird, finden Sie im CustomUsbDeviceAccess-Beispiel, Scenario2_ControlTransfer.cpp und Scenario2_ControlTransfer.h.
Schritt 1: Auffüllen des Einrichtungspakets
In diesem Thema senden wir eine Steuerungsübertragung an ein Gerät, das in verschiedenen Mustern blinkt. Um das Einrichtungspaket aufzufüllen, müssen Sie die Steuerungsbefehle kennen, die vom Hardwareanbieter definiert sind:
- bmRequestType (D7): OUT
- bmRequestType (D4): Gerät
- bmRequestType (D6... D5): Anbieter
- bRequest: 0x03
- wValue: 0-7 (beliebige Zahl in diesem Bereich, inklusive)
- wIndex: 0
- wLength: 0
Für die Steuerungsübertragung müssen Sie ein Einrichtungspaket auffüllen, das alle Informationen zur Übertragung enthält. Ungeachtet, ob die Anforderung Daten liest oder schreibt, des Anforderungstyps usw. Das Format des Einrichtungspakets wird in der offiziellen USB-Spezifikation definiert. Die Werte von Einrichtungspaketfeldern werden von der Hardwarespezifikation des Geräts bereitgestellt.
Erstellen Sie ein UsbSetupPacket-Objekt.
Füllen Sie das UsbSetupPacket-Objekt auf, indem Sie verschiedene Eigenschaften festlegen. Diese Tabelle enthält die USB-definierten Einrichtungspaketfelder und die Eigenschaften, die diesen Feldern entsprechen:
Felder in Abschnitt 9.3 Eigenschaft Beschreibung bmRequestType (D7) UsbControlRequestType.Direction Richtung der Anforderung. Gibt an, ob die Anforderung vom Host zum Gerät (Out-Übertragungen) oder vom Gerät zum Host (In-Übertragungen) stammt. bmRequestType (D4) UsbControlRequestType.Recipient Empfänger der Anforderung. Alle Steuerungsübertragungen zielen auf den Standardendpunkt ab. Der Empfänger kann jedoch Gerät, Schnittstelle, Endpunkt oder andere sein. Weitere Informationen zu USB-Geräten, Schnittstellen und Endpunkthierarchien finden Sie unter Gerätelayout. bmRequestType (D6...D5) UsbControlRequestType.ControlTransferType Anforderungskategorie. Standard, Klasse oder Anbieter. bRequest UsbSetupPacket.Request Der Anforderungstyp. Wenn es sich bei der Anforderung um eine Standardanforderung handelt, z. B. eine GET_DESCRIPTOR-Anforderung, wird diese Anforderung durch die USB-Spezifikation definiert. Andernfalls könnte es vom Anbieter definiert sein. wValue UsbSetupPacket.Value Hängt vom Typ der Anforderung ab. wIndex UsbSetupPacket.Index Hängt vom Typ der Anforderung ab. wLength UsbSetupPacket.Length Länge des in dieser Anforderung gesendeten oder empfangenen Datenpakets.
![HINWEIS] Bei bestimmten Steuerungsübertragungen müssen Sie möglicherweise bmRequestType als unformatiertes Byte bereitstellen. In diesem Fall können Sie das Byte in der UsbControlRequestType.AsByte-Eigenschaft festlegen.
Schritt 2: Starten eines asynchronen Vorgangs zum Senden der Steuerungsübertragung
Zum Senden von Steuerungsübertragungen benötigen Sie ein UsbDevice-Objekt. Ihre Steuerungsübertragung erfordert möglicherweise Datenpakete, die dem Einrichtungspaket entsprechen.
Rufen Sie zum Initiieren einer Steuerungsübertragung eine Außerkraftsetzung von SendControlInTransferAsync oder SendControlOutTransferAsync auf. Wenn die Übertragung Datenpakete verwendet, rufen Sie SendControlOutTransferAsync (UsbSetupPacket, IBuffer), SendControlInTransferAsync (UsbSetupPacket, IBuffer) auf. Diese Methoden verwenden einen zusätzlichen Parameter, der die zu schreibenden Daten enthält oder Daten vom Gerät empfängt. Verwenden Sie das Flussdiagramm, um zu bestimmen, welche Außerkraftsetzung aufgerufen werden soll.
Der Aufruf startet einen asynchronen Vorgang. Nach Abschluss des Vorgangs gibt der Aufruf das IAsyncOperation-Objekt zurück, das Ergebnisse des Vorgangs enthält. Bei einer OUT-Übertragung gibt das Objekt die Anzahl der in einer Übertragung gesendeten Bytes zurück. Bei einer IN-Übertragung enthält das Objekt den Puffer, der Daten enthält, die vom Gerät gelesen wurden.
Beispielcode für USB-Steuerungsübertragungen
Dieser Beispielcode zeigt, wie Sie eine Steuerungsübertragung senden, die das blinkende Muster auf dem SuperMUTT-Gerät ändert. Das Einrichtungspaket für die Übertragung enthält einen vom Anbieter definierten Befehl. Das Beispiel befindet sich in Scenario2_ControlTransfer.cpp.
async Task SetSuperMuttLedBlinkPatternAsync(Byte pattern)
{
UsbSetupPacket initSetupPacket = new UsbSetupPacket
{
RequestType = new UsbControlRequestType
{
Direction = UsbTransferDirection.Out,
Recipient = UsbControlRecipient.Device,
ControlTransferType = UsbControlTransferType.Vendor
},
Request = SuperMutt.VendorCommand.SetLedBlinkPattern,
Value = pattern,
Length = 0
};
UInt32 bytesTransferred = await EventHandlerForDevice.Current.Device.SendControlOutTransferAsync(initSetupPacket);
MainPage.Current.NotifyUser("The Led blink pattern is set to " + pattern.ToString(), NotifyType.StatusMessage);
}
Dieser Beispielcode zeigt, wie Sie eine Steuerungsübertragung senden, die das blinkende Muster auf dem SuperMUTT-Gerät ändert. Das Einrichtungspaket für die Übertragung enthält einen vom Anbieter definierten Befehl. Das Beispiel befindet sich in Scenario2_ControlTransfer.cpp.
async Task<IBuffer> SendVendorControlTransferInToDeviceRecipientAsync(Byte vendorCommand, UInt32 dataPacketLength)
{
// Data will be written to this buffer when we receive it
var buffer = new Windows.Storage.Streams.Buffer(dataPacketLength);
UsbSetupPacket initSetupPacket = new UsbSetupPacket
{
RequestType = new UsbControlRequestType
{
Direction = UsbTransferDirection.In,
Recipient = UsbControlRecipient.Device,
ControlTransferType = UsbControlTransferType.Vendor,
},
Request = vendorCommand,
Length = dataPacketLength
};
return await EventHandlerForDevice.Current.Device.SendControlInTransferAsync(initSetupPacket, buffer);
}