如何傳送 USB 控制件傳輸 (UWP 應用程式)
本文示範:
- 如何格式化 USB 設定封包
- 如何從您的應用程式起始 USB 控制項傳輸
重要 API
與 USB 裝置通訊的應用程式通常會傳送數個控制傳輸要求。 這些要求會取得裝置的相關信息,並傳送硬體廠商所定義的控制命令。 在本主題中,您將瞭解如何控制傳輸,以及如何在 UWP 應用程式中格式化和傳送它們。
控制傳輸可以讀取或寫入設定資訊,或執行硬體廠商所定義的裝置特定功能。 如果傳輸執行寫入作業,則為 OUT 傳輸;讀取作業,它是 IN 傳輸。 無論方向為何,主機系統上的軟體,例如 UWP 應用程式,一律會建置並起始控件傳輸的要求。 有時,您的應用程式可以起始控制傳輸,以讀取或寫入數據。 在此情況下,您可能需要傳送額外的緩衝區。
為了容納所有類型的控制傳輸, Windows.Devices.Usb 提供下列方法:
- SendControlOutTransferAsync (UsbSetupPacket)
- SendControlInTransferAsync (UsbSetupPacket)
- SendControlOutTransferAsync (UsbSetupPacket, IBuffer)
- SendControlInTransferAsync (UsbSetupPacket, IBuffer)
USB 控制傳輸也可用來取得描述元數據或傳送標準命令。 不過,建議您呼叫 Windows.Devices.Usb 所提供的特定方法,而不是手動建置控件傳輸,以傳送這些類型的要求。 例如,若要選取替代設定,請呼叫 SelectSettingAsync,而不是呼叫 SendControlOutTransferAsync (UsbSetupPacket)。
不支援特定類型的標準要求控制傳輸。 不過,如果您的裝置屬於 Windows.Devices.Usb 支援的裝置類別,您可以傳送裝置類別規格所定義的一些要求。
在您開始使用 Intune 之前
- 您必須開啟裝置並取得 UsbDevice 物件。 請參閱 如何連線到 USB 裝置 (UWP app) 。
- 取得廠商定義控制項命令的相關信息。 這些命令通常會在硬體規格中定義。
- 您可以在 CustomUsbDeviceAccess 範例Scenario2_ControlTransfer.cpp和 Scenario2_ControlTransfer.h 中看到本主題中顯示的完整程式代碼。
步驟 1:填入設定封包
在本主題中,我們會將控件傳輸傳送至以各種模式閃爍燈光的裝置。 若要填入設定封包,您必須知道硬體廠商已定義控制命令:
- bmRequestType (D7): OUT
- bmRequestType (D4): 裝置
- bmRequestType (D6...D5): 廠商
- bRequest: 0x03
- wValue: 0-7 (該範圍中的任何數位,包含)
- wIndex: 0
- wLength: 0
針對控制傳輸,您必須填入 包含傳輸相關信息的設定封包 ;無論要求讀取或寫入數據、要求類型等等。 設定封包的格式定義在官方USB規格中。 設定封包欄位的值是由裝置的硬體規格所提供。
建立 UsbSetupPacket 物件。
藉由設定各種屬性,填入 UsbSetupPacket 物件。 下表顯示 USB 定義的設定封包欄位,以及對應至這些欄位的屬性:
第9.3節中的欄位 屬性 說明 bmRequestType (D7) UsbControlRequestType.Direction 要求的方向。 要求是從主機到裝置(外傳輸)還是裝置到主機(傳輸中) bmRequestType (D4) UsbControlRequestType.Recipient 要求的收件者。 所有控制件都會以預設端點為目標。 不過,收件者可能是裝置、介面、連接點或其他。 如需 USB 裝置、介面、端點階層的詳細資訊,請參閱裝置配置。 bmRequestType (D6...D5) UsbControlRequestType.ControlTransferType 要求類別。 標準、類別或廠商。 bRequest UsbSetupPacket.Request 要求類型。 如果要求是標準要求,例如GET_DESCRIPTOR要求,該要求是由USB規格所定義。 否則,它可以是廠商定義的。 wValue UsbSetupPacket.Value 取決於要求的類型。 wIndex UsbSetupPacket.Index 取決於要求的類型。 wLength UsbSetupPacket.Length 在此要求中傳送或接收的數據封包長度。
![注意]針對特定控件傳輸,您可能需要提供 bmRequestType 做為原始位元組。 在此情況下,您可以在UsbControlRequestType.AsByte屬性中設定位元組。
步驟 2:啟動異步操作以傳送控制傳輸
若要傳送控制傳輸,您必須具有 UsbDevice 物件。 您的控制傳輸可能或可能不需要遵循設定封包的數據封包。
若要起始控件傳輸,請呼叫 SendControlInTransferAsync 或 SendControlOutTransferAsync 的覆寫。 如果傳輸使用數據封包,則呼叫 SendControlOutTransferAsync (UsbSetupPacket、IBuffer)、 SendControlInTransferAsync (UsbSetupPacket、IBuffer) 。 這些方法會採用額外的參數,其中包含要從裝置寫入或接收數據的數據。 使用流程圖來判斷要呼叫的覆寫。
呼叫會啟動和異步操作。 作業完成時,呼叫會傳回 包含作業結果的 IAsyncOperation 物件。 如果是 OUT 傳輸,物件會傳回傳送中傳送的位元組數目。 如果是 IN 傳輸,物件會包含緩衝區,其中包含從裝置讀取的數據。
USB 控制件傳輸程式代碼範例
此範例程式代碼示範如何傳送控件傳輸,以變更 SuperMUTT 裝置上的閃爍模式。 傳輸的設定封包包含廠商定義的命令。 此範例位於 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);
}
此範例程式代碼示範如何傳送控件傳輸,以變更 SuperMUTT 裝置上的閃爍模式。 傳輸的設定封包包含廠商定義的命令。 此範例位於 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);
}