前言:
爲了方便查看博客,特意申請了一個公衆號,附上二維碼,有興趣的朋友可以關注,和我一起討論學習,一起享受技術,一起成長。
1. 概述
USB 描述符信息存儲在 USB 設備中,在枚舉過程中,USB 主機會向 USB 設備發送 GetDescriptor 請求,USB 設備在收到這個請求之後,會將 USB 描述符信息返回給 USB 主機,USB 主機分析返回來的數據,判斷出該設備是哪一種 USB 設備,建立相應的數據鏈接通道。
USB 設備使用描述符報告其屬性。描述符是具有定義格式的數據結構,每個描述符都以字節寬度字段開頭,該字段包含描述符中的總字節數,後跟一個標識描述符類型的字節寬度字段。在 USB 設備枚舉過程中,主機端的協義軟件需要解析從 USB 設備讀取的所有描述符信息。在 USB 主向設備發送讀取描述符的請求後,USB 設備將所有的描述符以連續的數據流方式傳輸給 USB 主機。主機從第一個讀到的字符開始,根據雙方規定好的數據格式,順序地解析讀到的數據流。
每個 USB 設備公開的設備描述符,指示設備的類信息、 供應商和產品標識符,以及多個配置。 每個配置還公開其配置描述符,該值指示大量接口和功耗特徵。 每個接口公開其包含類和數量的終結點信息的替代設置的每個接口描述符。 每個接口中的每個終結點公開終結點,描述符可指明終結點類型和最大數據包大小。
描述符類型:
標準的 USB 設備有 5 種 USB 描述符:設備描述符(Device Descriptor)、配置描述符(Configuration Descriptor)、接口描述符(Interface Descriptor)、端點描述符(Endpoint Descriptor)和字符串描述符(String Descriptor)。描述符具有類似的格式,它們的第一個字段都是 bLength,第二個字段都是 bDescriptorType。七種描述符在使用時以 bDescriptorType 字段來區分。一設備至少要包含設備描述符、配置描述符和接口描述符,如果USB 設備沒有端點描述符,則它僅僅用默認管道與主機進行數據傳輸。
每個 USB 設備只有一個設備描述符,而一個設備中可包含一個或多個配置描述符,即 USB 設備可以有多種配置。設備的每一個配置中又可以包含一個或多個接口描述符,即 USB 設備可以支持多種功能(接口),接口的特性通過描述符提供。
在 USB 主機訪問 USB 設備的描述符時,USB 設備依照設備描述符、配置描述符、接口描述符、端點描述符、字符串描述符順序將所有描述符傳給主機。一設備至少要包含設備描述符、配置描述符和接口描述符,如果 USB 設備沒有端點描述符,則它僅僅用默認管道與主機進行數據傳輸。
2. 設備描述符
設備描述符描述的是設備的整體信息,與設備本身一一對應,包括對設備及在設備配置中起全程作用的信息,包括製造商標識號 ID、產品序列號、所屬設備類號、默認端點的最大包長度和配置描述符的個數等。一個設備只能有一個設備描述符。在主機對 USB 設備枚舉的過程中,首先要做的就是獲取設備描述符,以對設備有一個整體的瞭解。
設備描述符由14個字段組成,總長度18字節:
typedef struct _USB_DEVICE_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
WORD bcdUSB, //2字節
BYTE bDeviceClass,
BTYE bDeviceSubClass,
BYTE bDeviceProtol,
BYTE bMaxPacketSize0,
WORD idVenderI, //2字節
WORD idProduct, //2字節
WORD bcdDevice, //2字節
BYTE iManufacturer,
BYTE iProduct,
BYTE iSerialNumber,
BYTE iNumConfiguations
}USB_DEVICE_DESCRIPTOR;
/*
b 一個字節,=8bits;
w 兩個字節,=16bits;
bm 按位尋址;
bcd 用BCD碼錶示;
i 索引值
id 標識碼
*/
解釋:
字段名 | 解釋 |
---|---|
bLength | 描述符大小,固定爲 0x12 |
bDescriptorType | 設備描述符類型,固定爲 0x01 |
bcdUSB | USB 規範發佈號,表示了本設備能適用於那種協議,如 2.0=0200,1.1=0110 等 |
bDeviceClass | 該設備所屬的標準設備類,USB 協議中對常見的設備進行了分類。該字段值爲 0x01~0xFE 時,表示是 USB 協議中已定義的設備類,常用的 HID 設備類編號爲 0x03 |
bDeviceSubClass | 子類型代碼(由USB分配),如果 bDeviceClass 值是 0,一定要設置爲 0.其它情況就跟據 USB-IF 組織定義的編碼 |
bDeviceProtocol | 協議代碼(由USB分配),如果使用 USB-IF 組織定義的協議,就需要設置這裏的值,否則直接設置爲 0。如果廠商自己定義的可以設置爲 FFH |
bMaxPacketSize0 | 端點 0 最大分組大小(只有 8,16,32,64 有效),對於低速 USB 設備,bMaxPacketSize0 爲8;對於全速 USB 設備,bMaxPacketSize0 爲 8、16、32、64;對於高速 USB 設備,bMaxPacketSize0 爲 64。 |
idVendor | 用於表示 USB 設備供應商的 ID。USB 組織中規定每種產品都必須包含一個供應商 ID,這樣可以使主機加載合適的驅動程序。 |
idProduct | 用於表示 USB 產品的 ID,由設備供應商提供。idProduct 用於表示特定的 USB 設備,在 USB 設備上電的時候可以幫助 USB 主機選擇合適的驅動程序。 |
bcdDevice | 用於表示 USB 設備的版本號,它以 BCD 碼的形式表示。一般來說 bcdDevcie 由設備供應商指定,在 USB 設備上電的時候可以幫助 USB 主機選擇合適的驅動程序。 |
iManufacturer | 廠商描述符字符串索引.索引到對應的字符串描述符. 爲 0 則表示沒有 |
iProduct | 產品描述符字符串索引 |
iSerialNumber | 用於表示設備序列號字符串描述符的索引值,如果沒有,可以置爲 0 |
bNumConfigurations | 用於表示該 USB 設備所支持的配置數。 |
一個 USB CCID 設備的描述符爲:與上表中的字段是一一對應的。
3. 配置描述符
配置描述符定義了設備的配置信息,一個設備可以有多個配置描述符。配置描述符中包括了描述符的長度(屬於此描述符的所有接口描述符和端點描述符的長度的和)、供電方式(自供電/總線供電)、最大耗電量等。主機發出 USB 標準命令 Get_Descriptor 要求得到設備的某個配置描述符,那麼除了此配置描述符以外,此配置包含的所有接口描述符與端點描述符都將提供給 USB 主機。
一個 USB 設備可以有多種配置,不同的配置使設備工作在不同的狀態下,每個配置必須有一個配置描述符。其格式包括 8 個字段,共 9 字節。
typedef struct _USB_CONFIGURATION_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
WORD wTotalLength,
BYTE bNumInterfaces,
BYTE bConfigurationValue,
BYTE iConfiguration,
BYTE bmAttributes,
BYTE bMaxPower
}USB_CONFIGURATION_DESCRIPTOR;
字段名 | 解釋 |
---|---|
bLength | 配置描述符長度,配置描述符長度爲 9 字節大小。 |
bDescriptorType | 描述符類型,配置描述符類型爲 0x02。 |
wTotalLength | 配置描述符信息總的大小,包括接口描述符、端點描述符等。 |
bNumInterfaces | USB 接口數量。 |
bConfigurationValue | 當使用 SetConfiguration 和 GetConfiguration 請求時所指定的配置索引值。 |
iConfiguration | 描述配置的字符串描述符索引。 |
bmAttributes | 供電配置,位詳細定義如下:D7 保留,必須置1;D6 自供電模式; D5 遠程喚醒; D4~D0 保留 |
bMaxPower | 最大功耗,以 2mA 爲單位,例如 0x32 爲 50*2 = 100mA。USB 設備可以從 USB 總線上獲得最大的電流爲 500mA,因此bMaxPower 字段的最大值可以設置爲 250。 |
示例:
4.接口描述符
如果一個配置描述符不止支持一個接口描述符,並且每個接口描述符都有一個或多個端點描述符,那麼在響應 USB主機的配置描述符命令時,USB 設備的端點描述符總是緊跟着相關的接口描述符後面,作爲配置描述符的一部分被返回。接口描述符不可直接用 Set_Descriptor 和 Get_Descriptor 來存取。若一個接口僅使用端點 0,則接口描述符以後就不再返回端點描述符,並且此接口表現的是一個控制接口的特性,它使用與端點 0 相關聯的默認管道進行數據傳輸。在這種情況下 bNumberEndpoints 域應被設置成 0。接口描述符在說明端點個數並不把端點 0 計算在內。
接口是端點的集合,負責完成 USB 的特定功能,例如:數據的輸入輸出。接口描述符用於描述一個接口,包含了接口的特性,如端點個數,所屬設備類和子類等。它有 9 個字段,共 9 字節。
typedef struct _USB_INTERFACE_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
BYTE bInterfaceNumber,
BYTE bAlternateSetting,
BYTE bNumEndpoint,
BYTE bInterfaceClass,
BYTE bInterfaceSubClass,
BYTE bInterfaceProtocol,
BYTE iInterface
}USB_INTERFACE_DESCRIPTOR;
字段名 | 解釋 |
---|---|
bLength | 描述符大小.固定爲 0x09 |
bDescriptorType | 接口描述符類型.固定爲 0x04 |
bInterfaceNumber | 該接口的編號,接口編號從 0 開始分配,當一個配置有多個接口時,就用該字段來區分不同的接口。 |
bAlternateSetting | 用於爲上一個字段選擇可供替換的位置,即備用的接口描述符標號 |
bNumEndpoint | 使用的端點數目.端點 0 除外,如果此值爲 0 ,此接口僅僅只能被用爲控制管道 |
bInterfaceClass | 接口所屬的類值: 零值爲將來的標準保留,如果此域的值設爲 FFH,則此接口類由廠商說明,所有其它的值由 USB 說明保留。 |
bInterfaceSubClass | 子類碼 :這些值的定義視 bInterfaceClass 域而定。 如果 bInterfaceClass 域的值爲零則此域的值必須爲零。 bInterfaceClass 域不爲 FFH 則所有值由 USB 所保留。 |
bInterfaceProtocol | 協議碼:bInterfaceClass 和 bInterfaceSubClass 域的值而定.如果一個接口支持設備類相關的請求此域的值指出了設備類說明中所定義的協議. |
iInterface | 描述此接口的字串描述表的索引值。 |
接口描述符返回示例:
對於 bInterfaceClass 字段,表示接口所屬的類別,USB 協議根據功能將不同的接口劃分成不的類,其具體含義如下表所示:
值 | 類別 |
---|---|
0x01 | 音頻類 |
0x02 | CDC控制類 |
0x03 | 人機接口類(HID) |
0x05 | 物理類 |
0x06 | 圖像類 |
0x07 | 打印機類 |
0x08 | 大數據存儲類 |
0x09 | 集線器類 |
0x0A | CDC數據類 |
0x0B | 智能卡類 |
0x0D | 安全類 |
0xDC | 診斷設備類 |
0xE0 | 無線控制器類 |
0xFE | 特定應用類(包括紅外的橋接器等) |
0xFF | 廠商定義的設備 |
5.端點描述符
端點是設備與主機之間進行數據傳輸的邏輯接口,除配置使用的端點 0(控制端點,一般一個設備只有一個控制端點)爲雙向端口外,其它均爲單向。端點描述符描述了數據的傳輸類型、傳輸方向、數據包大小和端點號(也可稱爲端點地址)等。
除了描述符中描述的端點外,每個設備必須要有一個默認的控制型端點,地址爲 0,它的數據傳輸爲雙向,而且沒有專門的描述符,只是在設備描述符中定義了它的最大包長度。主機通過此端點向設備發送命令,獲得設備的各種描述符的信息,並通過它來配置設備。
USB 設備中的每個端點都有自己的端點描述符,由接口描述符中的 bNumEndpoint 決定其數量。
typedef struct _USB_ENDPOINT_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
BYTE bEndpointAddress,
BYTE bmAttributes,
WORD wMaxPacketSize,
BYTE bInterval
}USB_ENDPOINT_DESCRIPTOR;
字段名 | 解釋 |
---|---|
bLength | 描述符大小.固定爲 0x07。 |
bDescriptorType | 接口描述符類型.固定爲 0x05。 |
bEndpointAddress | 此描述表所描述的端點的地址、方向: Bit 3…0 : 端點號;Bit 6…4 : 保留,爲零 ;Bit 7: 方向,如果控制端點則略。 0:輸出端點(主機到設備) ;1:輸入端點(設備到主機) |
bmAttributes | 此域的值描述的是在 bConfigurationValue 域所指的配置下端點的特性。 Bit 1…0 :傳送類型 (00=控制傳送 ;01=同步傳送 ;10=批量傳送 ;11=中斷傳送 ,所有其它的位都保留。 |
wMaxPacketSize | 當前配置下此端點能夠接收或發送的最大數據包的大小。 對於實進傳輸,此值用於爲每幀的數據淨負荷預留時間。在實際運行時,管道可能不完全需要預留的帶寬,實際帶寬可由設備通過一種非 USB 定義的機制彙報給主機。對於中斷傳輸,批量傳輸和控制傳輸,端點可能發送比之短的數據包 |
bInterval | 週期數據傳輸端點的時間間隙。 此域的值對於批傳送的端點及控制傳送的端點無意義。對於同步傳送的端點此域必需爲 1,表示週期爲 1ms。對於中斷傳送的端點此域值的範圍爲 1ms 到 255ms。 |
端點描述符實例,一個輸入、一個輸出:
6.字符串描述符
字符串描述符是一種可選的 USB 標準描述符,描述瞭如制商、設備名稱或序列號等信息。如果一個設備無字符串描述符,則其它描述符中與字符串有關的索引值都必須爲 0。字符串使用的是 Unicode 編碼。
主機請示得到某個字符串描述符時一般分成兩步:首先主機向設備發出 USB 標準命令 Get_Descriptor,其中所使用的字符串的索引值爲 0,設備返回一個字符串描述符,此描述符的結構如下:
USB 設備中的字符串可能支持多種語言。請求字符串描述符時,請求者使用 USB-IF 定義的 16 位語ID(LANGID)指定所需的語言。所有語言的字符串索引零都返回一個字符串描述符,該描述符包含設備支持的雙字節 LANGID 代碼數組。上圖表顯示了 LANGID 代碼數組。 USB 設備可以省略所有字符串描述符。省略所有字符串描述符的 USB 設備不得返回 LANGID 代碼數組。
LANGID 代碼數組不以 NULL 結尾。通過從描述符的第一個字節的值中減去兩個來計算數組的大小(以字節爲單位)。
UNICODE字符串描述符:
typedef struct _USB_STRING_DESCRIPTION_
{
BYTE bLength,
BYTE bDescriptionType,
BYTE bString[1];
}USB_STRING_DESCRIPTION;
字段名 | 解釋 |
---|---|
bLength | 描述符大小.由整個字符串的長度加上 bLength 和 bDescriptorType 的長度決定(N+2) |
bDescriptorType | 接口描述符類型.固定爲 0x03 |
bString | Unicode 編碼字符串(長度爲 N) |
7.設備限定描述符
device_qualifier 描述符描述了有關高速設備的信息,如果設備以其他速度運行,該設備將發生變化。如果設備當前正以全速運行,則 device_qualifier 將返回有關其如何以高速運行的信息。
標準設備描述符的供應商,產品,設備,製造商,產品和序列號字段不包含在此描述符中,因爲該信息對於所有支持的速度的設備是恆定的。 此描述符的版本號必須至少爲2.0(0200H)。主機使用GetDescriptor()請求訪問此描述符。
如果僅全速設備(設備描述符版本號等於0200H)收到對 device_qualifier 的 GetDescriptor()請求,則它必須響應請求錯誤。 除非首先成功檢索 device_qualifier 描述符,否則主機不得請求 other_speed_configuration 描述符。
struct USB_QUALIFIER_DESCRIPTOR
{
BYTE bLength;
BYTE bDescriptorType;
WORD bcdUSB;
BYTE bDeviceClass;
BYTE bDeviceSubClass;
BYTE bDeviceProtocol;
BYTE bMaxPacketSize0;
BYTE bNumConfigurations;
BYTE bRESERVED;
}
字段名 | 解釋 |
---|---|
bLength | 設備限定描述符長度,10 個字節(0AH) |
bDescriptorType | 限定描述符類型,固定爲 06H |
bcdUSB | USB 設備及其描述符遵循的 USB 規範版本號,以 BCD 碼形式表示,版本必須在 2.0 以上 |
bDeviceClass | USB 所屬的設備類 |
bDeviceSubClass | USB 所屬的設備子類,設備類再細分 |
bDeviceProtocol | 協議代碼(由USB分配),如果使用 USB-IF 組織定義的協議,就需要設置這裏的值,否則直接設置爲 0。如果廠商自己定義的可以設置爲 FFH |
bMaxPacketSize0 | 端點 0 最大分組大小(只有 8,16,32,64 有效),對於低速 USB 設備,bMaxPacketSize0 爲8;對於全速 USB 設備,bMaxPacketSize0 爲 8、16、32、64;對於高速 USB 設備,bMaxPacketSize0 爲 64。 |
bNumConfigurations | 表示 USB 設備另一個速率所支持的配置數 |
bRESERVED | 保留項,置0 |
注:此處針對 USB2.0 協議
參考:
1.從零開始學USB(十、USB的描述符)
2.USB描述符
3.USB描述符詳解
4.USB命令請求及描述符詳解(速查手冊)
5.USB中的描述符詳解[一]
6.USB請求和USB描述符
7.從零開始學USB(十、USB的描述符)