USB開(kāi)發(fā)基礎:USB命令(請求)和USB描述符
在USB規范里,對命令一詞提供的單詞為“Request”,但這里為了更好的理解主機與設備之間的主從關(guān)系,將它定義成“命令”。
所有的USB設備都要求對主機發(fā)給自己的控制命令作出響應,USB規范定義了11個(gè)標準命令,它們分別是:Clear_Feature、Get_Configuration、Get_Descriptor、Get_Interface、Get_Status、Set_Address、Set_Configuration、Set_Descriptor、Set_Interface、Set_Feature、Synch_Frame。所有USB設備都必須支持這些命令(個(gè)別命令除外,如Set_Descriptor、Synch_Frame)。
不同的命令雖然有不同的數據和使用目的,但所有的USB命令結構是一樣的。下表所示為USB命令的結構:
表1、USB命令的結構 | ||||
偏移量 | 域 | 長(cháng)度(字節) | 值 | 描述 |
0 | bmRequestType | 1 | 位圖 | 請求特征: D7:傳輸方向 0=主機至設備 1=設備至主機 D6..5:種類(lèi) 0=標準 1=類(lèi) 2=廠(chǎng)商 3=保留 D4..0:接受者 0=設備 1=接口 2=端點(diǎn) 3=其他 4..31保留 |
1 | bRequest | 1 | 值 | 命令類(lèi)型編碼值(見(jiàn)表3) |
2 | wValue | 2 | 值 | 根據不同的命令,含義也不同 |
4 | wIndex | 2 | 索引或偏移 | 根據不同的命令,含義也不同,主要用于傳送索引或偏 移 |
6 | wLength | 2 | 如有數據傳送階段,此為數據字節數。 |
表2、USB的11種標準命令 | ||||||
命令 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
Clear_Feature | 00000000B 00000001B 00000010B | CLEAR_FEATURE | 特性選擇符 | 零 接口號 端點(diǎn)號 | 零 | 無(wú) |
Get_Configuration | 10000000B | GET_CONFIGURATION | 零 | 零 | 一 | 配置值 |
Get_Descriptor | 10000000B | GET_DESCRIPTOR | 描述表種類(lèi)(高字節,見(jiàn)表5)和索引(低字節) | 零或語(yǔ)言標志 | 描述表長(cháng) | 描述表 |
Get_Interface | 10000001B | GET_INTERFACE | 零 | 接口號 | 一 | 可選設置 |
Get_Status | 10000000B 10000001B 10000010B | GET_STATUS | 零 | 零(返回設備狀態(tài)) 接口號(對像時(shí)接口時(shí)) 端點(diǎn)號(對象是端點(diǎn)時(shí)) | 二 | 設備, 接口,或 端點(diǎn)狀態(tài) |
Set_Address | 00000000B | SET_ADDRESS | 設備地址 | 零 | 零 | 無(wú) |
Set_Configuration | 00000000B | SET_CONFIGURATION | 配置值(高字節為0,低字節表示要設置的配置值) | 零 | 零 | 無(wú) |
Set_Descriptor | 00000000B | SET_DESCRIPTOR | 描述表種類(lèi)(高字節,見(jiàn)表5)和索引(低字節) | 零或語(yǔ)言標志 | 描述表長(cháng) | 描述表 |
Set_Feature | 00000000B 00000001B 00000010B | SET_FEATURE | 特性選擇符(1表示設備,0表示端點(diǎn)) | 零 接口號 端點(diǎn)號 | 零 | 無(wú) |
Set_Interface | 00000001B | SET_INTERFACE | 可選設置 | 接口號 | 零 | 無(wú) |
Synch_Frame | 100000010B | SYNCH_FRAME | 零 | 端點(diǎn)號 | 二 | 幀號 |
表3、USB標準命令的編碼值 | |
bRequest | Value |
GET_STATUS | 0 |
CLEAR_FEATURE | 1 |
為將來(lái)保留 | 2 |
SET_FEATURE | 3 |
為將來(lái)保留 | 4 |
SET_ADDRESS | 5 |
GET_DESCRIPTOR | 6 |
SET_DESCRIPTOR | 7 |
GET_CONFIGURATION | 8 |
SET_CONFIGURATION | 9 |
GET_INTERFACE | 10 |
SET_INTERFACE | 11 |
SYNCH_FRAME | 12 |
二、USB描述符
USB協(xié)議為USB設備定義了一套描述設備功能和屬性的有固定結構的描述符,包括標準的描述符即設備描述符、配置描述符、接口描述符、端點(diǎn)描述符和字符串描述符,還有百標準描述符,如類(lèi)描述符。USB設備通過(guò)這些描述符向USB主機匯報設備的各種各樣屬性,主機通過(guò)對這些描述符的訪(fǎng)問(wèn)對設備進(jìn)行類(lèi)型識別、配置并為其提供相應的客戶(hù)端驅動(dòng)程序。
USB設備通過(guò)描述符反映自己的設備特性。USB描述符是由特定格式排列的一組數據結構組成。
在USB設備枚舉過(guò)程中,主機端的協(xié)義軟件需要解析從USB設備讀取的所有描述符信息。在USB主向設備發(fā)送讀取描述符的請求后,USB設備將所有的描述符以連續的數據流方式傳輸給USB主機。主機從第一個(gè)讀到的字符開(kāi)始,根據雙方規定好的數據格式,順序地解析讀到的數據流。
USB描述符包含標準描述符、類(lèi)描述符和廠(chǎng)商特定描述3種形式。任何一種設備必須USB標準描述符(隊字符串描述符可選外)。
在USB1.X中,規定了5種標準描述符:設備描述符(Device Descriptor)、配置描述符(Configuration Descriptor)、接口描述符(Interface Descriptor)、端點(diǎn)描述符(Endpoint Descriptor)和字符串描述符(String Descriptor)。
每個(gè)USB設備只有一個(gè)設備描述符,而一個(gè)設備中可包含一個(gè)或多個(gè)配置描述符,即USB設備可以有多種配置。設備的每一個(gè)配置中又可以包含一個(gè)或多個(gè)接口描述符,即USB設備可以支持多種功能(接口),接口的特性通過(guò)描述符提供。
在USB主機訪(fǎng)問(wèn)USB設備的描述符時(shí),USB設備依照設備描述符、配置描述符、接口描述符、端點(diǎn)描述符、字符串描述符順序將所有描述符傳給主機。一設備至少要包含設備描述符、配置描述符和接口描述符,如果USB設備沒(méi)有端點(diǎn)描述符,則它僅僅用默認管道與主機進(jìn)行數據傳輸。
1、設備描述符
設備描述符給出了USB設備的一般信息,包括對設備及在設備配置中起全程作用的信息,包括制造商標識號ID、產(chǎn)品序列號、所屬設備類(lèi)號、默認端點(diǎn)的最大包長(cháng)度和配置描述符的個(gè)數等。一個(gè)USB設備必須有且僅有一個(gè)設備描述符。設備描述符是設備連接到總線(xiàn)上時(shí)USB主機所讀取的第一個(gè)描述符,它包含了14個(gè)字段,結構如下:
表4、USB設備描述符的結構 | ||||
偏移量 | 域 | 大小 | 值 | 描述 |
0 | bLength | 1 | 數字 | 此描述表的字節數 |
1 | bDecriptorType | 1 | 常量 | 描述符的類(lèi)型(此處應為0x01,即設備描述符) |
2 | bcdUSB | 2 | BCD碼 | 此設備與描述表兼容的USB設備說(shuō)明版本號(BCD碼) |
4 | bDeviceClass | 1 | 類(lèi) | 設備類(lèi)碼: 如果此域的值為0則一個(gè)設置下每個(gè)接口指出它自己的類(lèi),各個(gè)接口各自獨立工作。 如果此域的值處于1~FEH之間,則設備在不同的接口上支持不同的類(lèi)。并這些接口可能不能獨立工作。此值指出了這些接口集體的類(lèi)定義。 如果此域設為FFH,則此設備的類(lèi)由廠(chǎng)商定義。 |
5 | bDeviceSubClass | 1 | 子類(lèi) | 子類(lèi)挖碼 這些碼值的具體含義根據bDeviceClass域來(lái)看。 如bDeviceClass域為零,此域也須為零 如bDeviceClass域為FFH,此域的所有值保留。 |
6 | bDevicePortocol | 1 | 協(xié)議 | 協(xié)議碼 這些碼的值視bDeviceClass和bDeviceSubClass的值而定。 如果設備支持設備類(lèi)相關(guān)的協(xié)議,此碼標志了設備類(lèi)的值。如果此域的值為零,則此設備不支持設備類(lèi)相關(guān)的協(xié)議,然而,可能它的接口支持設備類(lèi)相關(guān)的協(xié)議。如果此域的值為FFH,此設備使用廠(chǎng)商定義的協(xié)議。 |
7 | bMaxPacketSize0 | 1 | 數字 | 端點(diǎn)0的最大包大?。▋H8,16,32,64 為合法值) |
8 | idVendor | 2 | ID | 廠(chǎng)商標志(由USB-IF組織賦值) |
10 | idProduct | 2 | ID | 產(chǎn)品標志(由廠(chǎng)商賦值) |
12 | bcdDevice | 2 | BCD碼 | 設備發(fā)行號(BCD碼) |
14 | iManufacturer | 1 | 索引 | 描述廠(chǎng)商信息的字符串描述符的索引值。 |
15 | iProduct | 1 | 索引 | 描述產(chǎn)品信息的字串描述符的索引值。 |
16 | iSerialNumber | 1 | 索引 | 描述設備序列號信息的字串描述符的索引值。 |
17 | bNumConfigurations | 1 | 數字 | 可能的配置描述符數目 |
表5、USB描述符的類(lèi)型值 | ||
類(lèi)型 | 描述符 | 描述符值 |
標準描述符 | 設備描述符(Device Descriptor) | 0x01 |
配置描述符(Configuration Descriptor) | 0x02 | |
字符串描述符(String Descriptor) | 0x03 | |
接口描述符(Interface Descriptor) | 0x04 | |
端點(diǎn)描述符(EndPont Descriptor) | 0x05 | |
類(lèi)描述符 | 集線(xiàn)器類(lèi)描述符(Hub Descriptor) | 0x29 |
人機接口類(lèi)描述符(HID) | 0x21 | |
廠(chǎng)商定義的描述符 | 0xFF |
表6、設備的類(lèi)別(bDeviceClass) | ||
值(十進(jìn)制) | 值(十六進(jìn)制) | 說(shuō)明 |
0 | 0x00 | 接口描述符中提供類(lèi)的值 |
2 | 0x02 | 通信類(lèi) |
9 | 0x09 | 集線(xiàn)器類(lèi) |
220 | 0xDC | 用于診斷用途的設備類(lèi) |
224 | 0xE0 | 無(wú)線(xiàn)通信設備類(lèi) |
255 | 0xFF | 廠(chǎng)商定義的設備類(lèi) |
表7、一種鼠標的設備描述符示例 | |
字段 | 描述符值(十六制) |
bLength | 0x12 |
bDecriptorType | 0x01 |
bcdUSB | x0110 |
bDeviceClass | 0x00 |
bDeviceSubClass | 0x00 |
bDevicePortocol | 0x00 |
bMaxPacketSize0 | 0x08 |
idVendor | 0x045E(Microsoft Corporation) |
idProduct | 0x0047 |
bcdDevice | 0x300 |
iManufacturer | 0x01 |
iProduct | 0x03 |
iSerialNumber | 0x00 |
bNumConfigurations | 0x01 |
配置描述符中包括了描述符的長(cháng)度(屬于此描述符的所有接口描述符和端點(diǎn)描述符的長(cháng)度的和)、供電方式(自供電/總線(xiàn)供電)、最大耗電量等。主果主機發(fā)出USB標準命令Get_Descriptor要求得到設備的某個(gè)配置描述符,那么除了此配置描述符以外,此配置包含的所有接口描述符與端點(diǎn)描述符都將提供給USB主機。
表8、USB配置描述符的結構 | ||||
偏移量 | 域 | 大小 | 值 | 描述 |
0 | bLength | 1 | 數字 | 此描述表的字節數長(cháng)度。 |
1 | bDescriptorType | 1 | 常量 | 配置描述表類(lèi)型(此處為0x02) |
2 | wTotalLength | 2 | 數字 | 此配置信息的總長(cháng)(包括配置,接口,端點(diǎn)和設備類(lèi)及廠(chǎng)商定義的描述符) |
4 | bNumInterfaces | 1 | 數字 | 此配置所支持的接口個(gè)數 |
5 | bCongfigurationValue | 1 | 數字 | 在SetConfiguration()請求中用作參數來(lái)選定此配置。 |
6 | iConfiguration | 1 | 索引 | 描述此配置的字串描述表索引 |
7 | bmAttributes | 1 | 位圖 | 配置特性: D7:保留(設為一) D6:自給電源 D5:遠程喚醒 D4..0:保留(設為一) 一個(gè)既用總線(xiàn)電源又有自給電源的設備會(huì )在MaxPower域指出需要從總線(xiàn)取的電量。并設置D6為一。運行時(shí)期的實(shí)際電源模式可由GetStatus(DEVICE)請求得到。 |
8 | MaxPower | 1 | mA | 在此配置下的總線(xiàn)電源耗費量。以2mA為一個(gè)單位。 |
表9、一種硬盤(pán)的配置描述符示例 | |
字段 | 描述符值(十六進(jìn)制) |
bLength | 0x09 |
bDescriptorType | 0x02 |
wTotalLength | 0x01F |
bNumInterfaces | 0x01 |
bCongfigurationValue | 0x01 |
iConfiguration | 0x00 |
bmAttributes | 0x0C |
MaxPower | 0x32 |
配置描述符中包含了一個(gè)或多個(gè)接口描述符,這里的“接口”并不是指物理存在的接口,在這里把它稱(chēng)之為“功能”更易理解些,例如一個(gè)設備既有錄音的功能又有揚聲器的功能,則這個(gè)設備至少就有兩個(gè)“接口”。
如果一個(gè)配置描述符不止支持一個(gè)接口描述符,并且每個(gè)接口描述符都有一個(gè)或多個(gè)端點(diǎn)描述符,那么在響應USB主機的配置描述符命令時(shí),USB設備的端點(diǎn)描述符總是緊跟著(zhù)相關(guān)的接口描述符后面,作為配置描述符的一部分被返回。接口描述符不可直接用Set_Descriptor和Get_Descriptor來(lái)存取。
如果一個(gè)接口僅使用端點(diǎn)0,則接口描述符以后就不再返回端點(diǎn)描述符,并且此接口表現的是一個(gè)控制接口的特性,它使用與端點(diǎn)0相關(guān)聯(lián)的默認管道進(jìn)行數據傳輸。在這種情況下bNumberEndpoints域應被設置成0。接口描述符在說(shuō)明端點(diǎn)個(gè)數并不把端點(diǎn)0計算在內。
表10、USB接口描述符的結構 | ||||
偏移量 | 域 | 大小 | 值 | 說(shuō)明 |
0 | bLength | 1 | 數字 | 此表的字節數 |
1 | bDescriptorType | 1 | 常量 | 接口描述表類(lèi)(此處應為0x04) |
2 | bInterfaceNumber | 1 | 數字 | 接口號,當前配置支持的接口數組索引(從零開(kāi)始)。 |
3 | bAlternateSetting | 1 | 數字 | 可選設置的索引值。 |
4 | bNumEndpoints | 1 | 數字 | 此接口用的端點(diǎn)數量,如果是零則說(shuō)明此接口只用缺省控制管道。 |
5 | bInterfaceClass | 1 | 類(lèi) | 接口所屬的類(lèi)值: 零值為將來(lái)的標準保留。 如果此域的值設為FFH,則此接口類(lèi)由廠(chǎng)商說(shuō)明。 所有其它的值由USB說(shuō)明保留。 |
6 | bInterfaceSubClass | 1 | 子類(lèi) | 子類(lèi)碼 這些值的定義視bInterfaceClass域而定。 如果bInterfaceClass域的值為零則此域的值必須為零。 bInterfaceClass域不為FFH則所有值由USB所保留。 |
7 | bInterfaceProtocol | 1 | 協(xié)議 | 協(xié)議碼:bInterfaceClass和bInterfaceSubClass域的值而定.如果一個(gè)接口支持設備類(lèi)相關(guān)的請求此域的值指出了設備類(lèi)說(shuō)明中所定義的協(xié)議. |
8 | iInterface | 1 | 索引 | 描述此接口的字串描述表的索引值。 |
表11、USB協(xié)議定義的接口類(lèi)別(bInterfaceClass) | |
值(十六進(jìn)制) | 類(lèi)別 |
0x01 | 音頻類(lèi) |
0x02 | CDC控制類(lèi) |
0x03 | 人機接口類(lèi)(HID) |
0x05 | 物理類(lèi) |
0x06 | 圖像類(lèi) |
0x07 | 打印機類(lèi) |
0x08 | 大數據存儲類(lèi) |
0x09 | 集線(xiàn)器類(lèi) |
0x0A | CDC數據類(lèi) |
0x0B | 智能卡類(lèi) |
0x0D | 安全類(lèi) |
0xDC | 診斷設備類(lèi) |
0xE0 | 無(wú)線(xiàn)控制器類(lèi) |
0xFE | 特定應用類(lèi)(包括紅外的橋接器等) |
0xFF | 廠(chǎng)商定義的設備 |
端點(diǎn)是設備與主機之間進(jìn)行數據傳輸的邏輯接口,除配置使用的端點(diǎn)0(控制端點(diǎn),一般一個(gè)設備只有一個(gè)控制端點(diǎn))為雙向端口外,其它均為單向。端點(diǎn)描述符描述了數據的傳輸類(lèi)型、傳輸方向、數據包大小和端點(diǎn)號(也可稱(chēng)為端點(diǎn)地址)等。
除了描述符中描述的端點(diǎn)外,每個(gè)設備必須要有一個(gè)默認的控制型端點(diǎn),地址為0,它的數據傳輸為雙向,而且沒(méi)有專(zhuān)門(mén)的描述符,只是在設備描述符中定義了它的最大包長(cháng)度。主機通過(guò)此端點(diǎn)向設備發(fā)送命令,獲得設備的各種描述符的信息,并通過(guò)它來(lái)配置設備。
表12、USB端點(diǎn)描述符的結構 | ||||
偏移量 | 域 | 大小 | 值 | 說(shuō)明 |
0 | bLength | 1 | 數字 | 此描述表的字節數長(cháng)度 |
1 | bDescriptorType | 1 | 常量 | 端點(diǎn)描述表類(lèi)(此處應為0x05) |
2 | bEndpointAddress | 1 | 端點(diǎn) | 此描述表所描述的端點(diǎn)的地址、方向: Bit 3..0 :端點(diǎn)號. Bit 6..4 :保留,為零 Bit 7:方向,如果控制端點(diǎn)則略。 0:輸出端點(diǎn)(主機到設備) 1:輸入端點(diǎn)(設備到主機) |
3 | bmAttributes | 1 | 位圖 | 此域的值描述的是在bConfigurationValue域所指的配置下端點(diǎn)的特性。 Bit 1..0 :傳送類(lèi)型 00=控制傳送 01=同步傳送 10=批傳送 11=中斷傳送 所有其它的位都保留。 |
4 | wMaxPacketSize | 2 | 數字 | 當前配置下此端點(diǎn)能夠接收或發(fā)送的最大數據包的大小。 對于實(shí)進(jìn)傳輸,此值用于為每幀的數據凈負荷預留時(shí)間。在實(shí)際運行時(shí),管道可能不完全需要預留的帶寬,實(shí)際帶寬可由設備通過(guò)一種非USB定義的機制匯報給主機。對于中斷傳輸,批量傳輸和控制傳輸,端點(diǎn)可能發(fā)送比之短的數據包 |
6 | bInterval | 1 | 數字 | 周期數據傳輸端點(diǎn)的時(shí)間間隙。 此域的值對于批傳送的端點(diǎn)及控制傳送的端點(diǎn)無(wú)意義。對于同步傳送的端點(diǎn)此域必需為1,表示周期為1ms。對于中斷傳送的端點(diǎn)此域值的范圍為1ms到255ms。 |
表13、一種鼠標的端點(diǎn)描述符示例 | |
域 | 值(十六進(jìn)制) |
bLength | 0x07 |
bDescriptorType | 0x05 |
bEndpointAddress | 0x81 |
bmAttributes | 0x03 |
wMaxPacketSize | 0x04 |
bInterval | 0x0A |
字符串描述符是一種可選的USB標準描述符,描述了如制商、設備名稱(chēng)或序列號等信息。如果一個(gè)設備無(wú)字符串描述符,則其它描述符中與字符串有關(guān)的索引值都必須為0。字符串使用的是Unicode編碼。
主機請示得到某個(gè)字符串描述符時(shí)一般分成兩步:首先主機向設備發(fā)出USB標準命令Get_Descriptor,其中所使用的字符串的索引值為0,設備返回一個(gè)字符串描述符,此描述符的結構如下:
表14、USB字符串描述符(響應主機請求時(shí)返回的表示語(yǔ)言ID的字符串描述符) | ||||
偏移量 | 域 | 大小 | 值 | 描述 |
0 | bLength | 1 | N+2 | 此描述表的字節數 |
1 | bDescriptorType | 1 | 常量 | 字串描述表類(lèi)型(此處應為0x03) |
2 | wLANGID[0] | 2 | 數字 | 語(yǔ)言標識(LANGID) 碼0 |
… | … | … | … | … |
N | wLANGID[x] | 2 | 數字 | 語(yǔ)言標識(LANGID) 碼X |
主機根據自己需要的語(yǔ)言,再次向設備發(fā)出USB標準命令Get_Descriptor,指明所要求得到的字符串的索引值和語(yǔ)言。這次設備所返回的是Unicode編號的字符串描述符,其結構如下:
表15、Unicode字符串描述符(響應主機請求時(shí)真正表示字符串編碼的字符串描述符) | ||||
偏移量 | 域 | 大小 | 值 | 描述 |
0 | bLength | 1 | 數字 | 此描述表的字節數(bString域的數值N+2) |
1 | bDescriptorType | 1 | 常量 | 字串描述表類(lèi)型(此處應為0x03) |
2 | bString | N | 數字 | UNICODE編碼的字串 |
評論