【轉】USB命令(請求)和USB描述符
轉載自:http://hi.baidu.com/deep_pro/blog/item/0ca086af97ca15f1faed5016.html
一、USB命令
在USB規範裡,對命令一詞提供的單詞為“Request”,但這裡為了更好的理解主機與裝置之間的主從關係,將它定義成“命令”。
所有的USB裝置都要求對主機發給自己的控制命令作出響應,USB規範定義了11個標準命令,它們分別是:Clear_Feature、Get_Configuration、Get_Descriptor、Get_Interface、Get_Status、Set_Address、Set_Configuration、Set_Descriptor、Set_Interface、Set_Feature、Synch_Frame。所有USB裝置都必須支援這些命令(個別命令除外,如Set_Descriptor、Synch_Frame)。
所有的命令雖然有不同的資料和使用目的,有的USB命令結構是一樣的。下表所示為USB命令的結構:
表1、USB命令的結構 | ||||
偏移量 | 域 | 長度(位元組) | 值 | 描述 |
0 | bmRequestType | 1 | 點陣圖 | 請求特徵: D7:傳輸方向 0=主機至裝置 1=裝置至主機 D6..5:種類 0=標準 1=類 2=廠商 3=保留 D4..0:接受者 0=裝置 1=介面 2=端點 3=其他 4..31 保留 |
1 | bRequest | 1 | 值 | 命令型別編碼值(見表3) |
2 | wValue | 2 | 值 | 根據不同的命令,含義也不同 |
4 | wIndex | 2 | 索引或偏移 | 根據不同的命令,含義也不同,主要用於傳送索引或偏 移 |
6 | wLength | 2 | 如有資料傳送階段,此為資料位元組數。 |
下表列出了USB的11種標準命令
表2、USB的11種標準命令 | ||||||
命令 | bmRequestType |
bRequest |
wValue |
wIndex |
wLength |
Data |
Clear_Feature | 00000000B |
CLEAR_FEATURE |
特性選擇符 |
零 |
零 |
無 |
Get_Configuration | 10000000B |
GET_CONFIGURATION |
零 |
零 |
一 |
配置值 |
Get_Descriptor | 10000000B |
GET_DESCRIPTOR |
描述表種類(高位元組,見表5)和索引(低位元組) |
零或語言標誌 |
描述表長 |
描述表 |
Get_Interface | 10000001B |
GET_INTERFACE |
零 |
介面號 |
一 |
可選設定 |
Get_Status | 10000000B |
GET_STATUS |
零 |
零(返回裝置狀態) |
二 |
裝置, |
Set_Address | 00000000B |
SET_ADDRESS |
裝置地址 |
零 |
零 |
無 |
Set_Configuration | 00000000B |
SET_CONFIGURATION |
配置值(高位元組為0,低位元組表示要設定的配置值) |
零 |
零 |
無 |
Set_Descriptor | 00000000B |
SET_DESCRIPTOR |
描述表種類(高位元組,見表5)和索引(低位元組) |
零或語言標誌 |
描述表長 |
描述表 |
Set_Feature | 00000000B |
SET_FEATURE |
特性選擇符(1表示裝置,0表示端點) |
零 |
零 |
無 |
Set_Interface | 00000001B |
SET_INTERFACE |
可選設定 |
介面號 |
零 |
無 |
Synch_Frame | 100000010B |
SYNCH_FRAME |
零 |
端點號 |
二 |
幀號 |
其中bRequest為命令編碼值,含意見表3:
表3、USB標準命令的編碼值 |
|
bRequest |
Value |
GET_STATUS |
0 |
CLEAR_FEATURE |
1 |
為將來保留 |
2 |
SET_FEATURE |
3 |
為將來保留 |
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協議為USB裝置定義了一套描述裝置功能和屬性的有固定結構的描述符,包括標準的描述符即裝置描述符、配置描述符、介面描述符、端點描述符和字串描述符,還有百標準描述符,如類描述符。USB裝置通過這些描述符向USB主機彙報裝置的各種各樣屬性,主機通過對這些描述符的訪問對裝置進行型別識別、配置併為其提供相應的客戶端驅動程式。
USB裝置通過描述符反映自己的裝置特性。USB描述符是由特定格式排列的一組資料結構組成。
在USB裝置列舉過程中,主機端的協義軟體需要解析從USB裝置讀取的所有描述符資訊。在USB主向裝置傳送讀取描述符的請求後,USB裝置將所有的描述符以連續的資料流方式傳輸給USB主機。主機從第一個讀到的字元開始,根據雙方規定好的資料格式,順序地解析讀到的資料流。
USB描述符包含標準描述符、類描述符和廠商特定描述3種形式。任何一種裝置必須USB標準描述符(隊字串描述符可選外)。
在USB1.X中,規定了5種標準描述符:裝置描述符(Device Descriptor)、配置描述符(Configuration Descriptor)、介面描述符(Interface Descriptor)、端點描述符(Endpoint Descriptor)和字串描述符(String Descriptor)。
每個USB裝置只有一個裝置描述符,而一個裝置中可包含一個或多個配置描述符,即USB裝置可以有多種配置。裝置的每一個配置中又可以包含一個或多個介面描述符,即USB裝置可以支援多種功能(介面),介面的特性通過描述符提供。
在USB主機訪問USB裝置的描述符時,USB裝置依照裝置描述符、配置描述符、介面描述符、端點描述符、字串描述符順序將所有描述符傳給主機。一裝置至少要包含裝置描述符、配置描述符和介面描述符,如果USB裝置沒有端點描述符,則它僅僅用預設管道與主機進行資料傳輸。
1、裝置描述符
裝置描述符給出了USB裝置的一般資訊,包括對裝置及在裝置配置中起全程作用的資訊,包括製造商標識號ID、產品序列號、所屬裝置類號、預設端點的最大包長度和配置描述符的個數等。一個USB裝置必須有且僅有一個裝置描述符。裝置描述符是裝置連線到總線上時USB主機所讀取的第一個描述符,它包含了14個欄位,結構如下:
表4、USB裝置描述符的結構 |
||||
偏移量 |
域 |
大小 |
值 |
描述 |
0 |
bLength |
1 |
數字 |
此描述表的位元組數 |
1 |
bDecriptorType |
1 |
常量 |
描述符的型別(此處應為0x01,即裝置描述符) |
2 |
bcdUSB |
2 |
BCD碼 |
此裝置與描述表相容的USB裝置說明版本號(BCD 碼) |
4 |
bDeviceClass |
1 |
類 |
裝置類碼: |
5 |
bDeviceSubClass |
1 |
子類 |
子類挖碼 |
6 |
bDevicePortocol |
1 |
協議 |
協議碼 |
7 |
bMaxPacketSize0 |
1 |
數字 |
端點0的最大包大小(僅8,16,32,64 |
8 |
idVendor |
2 |
ID |
廠商標誌(由USB-IF組織賦值) |
10 |
idProduct |
2 |
ID |
產品標誌(由廠商賦值) |
12 |
bcdDevice |
2 |
BCD 碼 |
裝置發行號(BCD 碼) |
14 |
iManufacturer |
1 |
索引 |
描述廠商資訊的字串描述符的索引值。 |
15 |
iProduct |
1 |
索引 |
描述產品資訊的字串描述符的索引值。 |
16 |
iSerialNumber |
1 |
索引 |
描述裝置序列號資訊的字串描述符的索引值。 |
17 |
bNumConfigurations |
1 |
數字 |
可能的配置描述符數目 |
其中bDescriptorType為描述符的型別,其含義可查下表(此表也適用於標準命令Get_Descriptor中wValue域高位元組的取值含義):
表5、USB描述符的型別值 |
||
型別 | 描述符 | 描述符值 |
標準描述符 | 裝置描述符(Device Descriptor) | 0x01 |
配置描述符(Configuration Descriptor) | 0x02 | |
字串描述符(String Descriptor) | 0x03 | |
介面描述符(Interface Descriptor) | 0x04 | |
端點描述符(EndPont Descriptor) | 0x05 | |
類描述符 | 集線器類描述符(Hub Descriptor) | 0x29 |
人機介面類描述符(HID) | 0x21 | |
廠商定義的描述符 | 0xFF |
裝置類程式碼bDeviceClass可查下表:
表6、裝置的類別(bDeviceClass) |
||
值(十進位制) |
值(十六進位制) |
說明 |
0 |
0x00 |
介面描述符中提供類的值 |
2 |
0x02 |
通訊類 |
9 |
0x09 |
集線器類 |
220 |
0xDC |
用於診斷用途的裝置類 |
224 |
0xE0 |
無線通訊裝置類 |
255 |
0xFF |
廠商定義的裝置類 |
下表列出了一個USB滑鼠的裝置描述符的例子,供大家分析一下:
表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 |
2、配置描述符
配置描述符中包括了描述符的長度(屬於此描述符的所有介面描述符和端點描述符的長度的和)、供電方式(自供電/匯流排供電)、最大耗電量等。主果主機發出USB標準命令Get_Descriptor要求得到裝置的某個配置描述符,那麼除了此配置描述符以外,此配置包含的所有介面描述符與端點描述符都將提供給USB主機。
表8、USB配置描述符的結構 | ||||
偏移量 |
域 |
大小 |
值 |
描述 |
0 |
bLength |
1 |
數字 |
此描述表的位元組數長度。 |
1 |
bDescriptorType |
1 |
常量 |
配置描述表型別(此處為0x02) |
2 |
wTotalLength |
2 |
數字 |
此配置資訊的總長(包括配置,介面,端點和裝置類及廠商定義的描述符) |
4 |
bNumInterfaces |
1 |
數字 |
此配置所支援的介面個數 |
5 |
bCongfigurationValue |
1 |
數字 |
在SetConfiguration()請求中用作引數來選定此配置。 |
6 |
iConfiguration |
1 |
索引 |
描述此配置的字串描述表索引 |
7 |
bmAttributes |
1 |
點陣圖 |
配置特性: |
8 |
MaxPower |
1 |
mA |
在此配置下的匯流排電源耗費量。以 2mA 為一個單位。 |
下面是一種硬碟的配置描述符示例:
表9、一種硬碟的配置描述符示例 | |
欄位 | 描述符值(十六進位制) |
bLength |
0x09 |
bDescriptorType |
0x02 |
wTotalLength |
0x01F |
bNumInterfaces |
0x01 |
bCongfigurationValue |
0x01 |
iConfiguration |
0x00 |
bmAttributes |
0x0C |
MaxPower |
0x32 |
3、介面描述符
配置描述符中包含了一個或多個介面描述符,這裡的“介面”並不是指物理存在的介面,在這裡把它稱之為“功能”更易理解些,例如一個裝置既有錄音的功能又有揚聲器的功能,則這個裝置至少就有兩個“介面”。
如果一個配置描述符不止支援一個介面描述符,並且每個介面描述符都有一個或多個端點描述符,那麼在響應USB主機的配置描述符命令時,USB裝置的端點描述符總是緊跟著相關的介面描述符後面,作為配置描述符的一部分被返回。介面描述符不可直接用Set_Descriptor和Get_Descriptor來存取。
如果一個介面僅使用端點0,則介面描述符以後就不再返回端點描述符,並且此介面表現的是一個控制介面的特性,它使用與端點0相關聯的預設管道進行資料傳輸。在這種情況下bNumberEndpoints域應被設定成0。介面描述符在說明端點個數並不把端點0計算在內。
表10、USB介面描述符的結構 | ||||
偏移量 |
域 |
大小 |
值 |
說明 |
0 |
bLength |
1 |
數字 |
此表的位元組數 |
1 |
bDescriptorType |
1 |
常量 |
介面描述表類(此處應為0x04) |
2 |
bInterfaceNumber |
1 |
數字 |
介面號,當前配置支援的介面陣列索引(從零開始)。 |
3 |
bAlternateSetting |
1 |
數字 |
可選設定的索引值。 |
4 |
bNumEndpoints |
1 |
數字 |
此介面用的端點數量,如果是零則說明此介面只用預設控制管道。 |
5 |
bInterfaceClass |
1 |
類 |
介面所屬的類值: |
6 |
bInterfaceSubClass |
1 |
子類 |
子類碼 |
7 |
bInterfaceProtocol |
1 |
協議 |
協議碼:bInterfaceClass 和bInterfaceSubClass 域的值而定.如果一個介面支援裝置類相關的請求此域的值指出了裝置類說明中所定義的協議. |
8 |
iInterface |
1 |
索引 |
描述此介面的字串描述表的索引值。 |
對於bInterfaceClass欄位,表示介面所屬的類別,USB協議根據功能將不同的介面劃分成不的類,其具體含義如下表所示:
表11、USB協議定義的介面類別(bInterfaceClass) | |
值(十六進位制) | 類別 |
0x01 | 音訊類 |
0x02 | CDC控制類 |
0x03 | 人機介面類(HID) |
0x05 | 物理類 |
0x06 | 影象類 |
0x07 | 印表機類 |
0x08 | 大資料儲存類 |
0x09 | 集線器類 |
0x0A | CDC資料類 |
0x0B | 智慧卡類 |
0x0D | 安全類 |
0xDC | 診斷裝置類 |
0xE0 | 無線控制器類 |
0xFE | 特定應用類(包括紅外的橋接器等) |
0xFF | 廠商定義的裝置 |
4、端點描述符
端點是裝置與主機之間進行資料傳輸的邏輯介面,除配置使用的端點0(控制端點,一般一個裝置只有一個控制端點)為雙向埠外,其它均為單向。端點描述符描述了資料的傳輸型別、傳輸方向、資料包大小和端點號(也可稱為端點地址)等。
除了描述符中描述的端點外,每個裝置必須要有一個預設的控制型端點,地址為0,它的資料傳輸為雙向,而且沒有專門的描述符,只是在裝置描述符中定義了它的最大包長度。主機通過此端點向裝置傳送命令,獲得裝置的各種描述符的資訊,並通過它來配置裝置。
表12、USB端點描述符的結構 | ||||
偏移量 |
域 |
大小 |
值 |
說明 |
0 |
bLength |
1 |
數字 |
此描述表的位元組數長度 |
1 |
bDescriptorType |
1 |
常量 |
端點描述表類(此處應為0x05) |
2 |
bEndpointAddress |
1 |
端點 |
此描述表所描述的端點的地址、方向: |
3 |
bmAttributes |
1 |
點陣圖 |
此域的值描述的是在bConfigurationValue域所指的配置下端點的特性。 |
4 |
wMaxPacketSize |
2 |
數字 |
當前配置下此端點能夠接收或傳送的最大資料包的大小。 |
6 |
bInterval |
1 |
數字 |
週期數據傳輸端點的時間間隙。 |
下表是一種滑鼠的端點描述符的示例,該端點是一箇中斷端點:
表13、一種滑鼠的端點描述符示例 | |
域 | 值(十六進位制) |
bLength |
0x07 |
bDescriptorType |
0x05 |
bEndpointAddress |
0x81 |
bmAttributes |
0x03 |
wMaxPacketSize |
0x04 |
bInterval |
0x0A |
5、字串描述符
字串描述符是一種可選的USB標準描述符,描述瞭如制商、裝置名稱或序列號等資訊。如果一個裝置無字串描述符,則其它描述符中與字串有關的索引值都必須為0。字串使用的是Unicode編碼。
主機請示得到某個字串描述符時一般分成兩步:首先主機向裝置發出USB標準命令Get_Descriptor,其中所使用的字串的索引值為0,裝置返回一個字串描述符,此描述符的結構如下:
表14、USB字串描述符(響應主機請求時返回的表示語言ID的字串描述符) | ||||
偏移量 |
域 |
大小 |
值 |
描述 |
0 |
bLength |
1 |
N+2 |
此描述表的位元組數 |
1 |
bDescriptorType |
1 |
常量 |
字串描述表型別(此處應為0x03) |
2 |
wLANGID[0] |
2 |
數字 |
語言標識(LANGID) |
|
… |
… |
… |
… |
N |
wLANGID[x] |
2 |
數字 |
語言標識(LANGID) |
該字串描述符雙位元組的語言ID的陣列,wLANGID[0]~wLANGID[x]指明瞭裝置支援的語言,具體含義可檢視USB_LANGIDs.pdf。
主機根據自己需要的語言,再次向裝置發出USB標準命令Get_Descriptor,指明所要求得到的字串的索引值和語言。這次裝置所返回的是Unicode編號的字串描述符,其結構如下:
表15、Unicode字串描述符(響應主機請求時真正表示字串編碼的字串描述符) | ||||
偏移量 |
域 |
大小 |
值 |
描述 |
0 |
bLength |
1 |
數字 |
此描述表的位元組數(bString域的數值N+2) |
1 |
bDescriptorType |
1 |
常量 |
字串描述表型別(此處應為0x03) |
2 |
bString |
N |
數字 |
UNICODE 編碼的字串 |
bString域為裝置實際返回的以UNICODE編碼的字串流,我們在編寫裝置端硬體驅動的時候需要將字串轉換為UNICODE編碼,您可以通過一些UNICODE轉換工具進行轉換。