USB設備描述符
字段名 | 長 度(字節) | 地址偏移 | 含 義 |
bLenth | 1 | 0 | 描述符長度 |
bDescriptorType | 1 | 1 | 描述符類型 (這里為 1) |
bcdUSB | 2 | 2 | USB規范版本號(BCD碼) |
bDeviceClass | 1 | 4 | 類代碼 |
bDeviceSubClass | 1 | 5 | 子類代碼 |
bDeviceProtocol | 1 | 6 | 協議代碼 |
bMaxPackSize0 | 1 | 7 | 端點0最大支持數據包長度 |
idVendor | 2 | 9 | 供應商ID |
idProduct | 2 | 11 | 產品ID |
bcdDevice | 2 | 13 | 設備版本號(BCD碼) |
iManufacturer | 1 | 14 | 供應商字符串描述索引 |
iProduct | 1 | 15 | 產品字符描述字符串索引 |
iSerialNumber | 1 | 16 | 產品序列好描述符索引 |
bNumConfigurations | 1 | 17 | 所支持的配置數 |
bLenth :該描述符的長度,單位字節一般USB設備描述符都是固定的18字節即0x12;
bDescriptorType :描述符種類代碼。USB設備描述符為0x01;
bcdUSB :USB協議版本,采用BCD編碼如2.0就是0x0200,但是USB是小端結構,因此實際就是 【0x00 ,0x20】
bDeviceClass: 設備類代碼,大多數是0而在接口描述符中的bInterfaceClass中指定該接口實現的功能,注意的是當bDeviceClass為0時,bDeviceSubClass也必須為0;
bDeviceSubClass :配合bDeviceClass代碼決定,USB標准定義。
bDeviceProtocol:設備所使用類的協議,如果沒有定義類就為0 ,字段為0xFF表示使用自定義協議。
bMaxPackSize0 :端點0的最大包長,最小是8,因為枚舉過程,第一次獲取設備描述符只會讀取一次,因此需要在這個包中包含USB設備描述符的長度。
idVendor:廠商ID VID,需要交保護費申請。
idProduct :產品ID PID由廠商自己定義。通常主機會根據VID和PID來加載本地或源的驅動程序。
bcdDevice :設備版本號,也采用BCD碼,同理USB協議版本號。
iSerialNumber :設備序列號字符串索引值。
bNumConfigurations :設備有多少種配置,大部分USB設備就只有一個配置。
USB配置描述符
需要注意的是在有些時候,配置描述符中會包含接口描述符,特殊類描述符,端點描述符等信息,並在主機枚舉請求設備配置描述符時一起返回給主機,不能單獨返回給主機。
字段名 | 長 度 (字 節) | 地址偏移量 | 含義 |
bLenth | 1 | 0 | 配置描述符長度 |
bDescriptorType | 1 | 1 | 配置描述符類型 |
wTotalLength | 2 | 2 | 配置信息總長度 |
bNumInterfaces | 1 | 4 | 配置接口數 |
bConfigurationValue | 1 | 5 | 配置值 |
iConfiguration | 1 | 6 | 字符串描述符索引值 |
bmAttributes | 1 | 7 | 配置特性 |
bMaxPower | 1 | 8 | 最大電流(2mA為單位) |
bLenth :該描述符長度
bDescriptorType:描述符類型,配置描述符為0x02;
wTotalLength:表示整個配置描述符的總長度,包括配置描述符,接口描述符,類特殊描述符和端點描述符。
bNumInterfaces:配置支持的接口數。
bConfigurationValue:每個配置都有一個標識值。
iConfiguration:配置描述符索引。
bmAttributes:描述特性 D7保留,D6辨識供電方式,為1表示自供電的,否則是總線供電,D5標識是否支持遠程喚醒(1),D4-D0保留。
bMaxPower:總線供電時的最大電流,如值為100則最大電流為200mA。
USB接口描述符
字 段 名 | 長 度 (字節) | 地址偏移 | 含 義 |
bLenth | 1 | 0 | 描述符的長度 |
bDescriptorType | 1 | 1 | 描述符的類型 |
bInterfaceNumber | 1 | 2 | 接口號 |
bAlterateSetting | 1 | 3 | 可替換設置值 |
bNumEndpoint | 1 | 4 | 端點0以外的端點數 |
bInterfaceClass | 1 | 5 | 類代碼 |
bInterfaceSubClass | 1 | 6 | 子類代碼 |
bInterfaceProtocol | 1 | 7 | 協議代碼 |
iInterface | 1 | 8 | 字符串描述符索引值 |
bLenth: 描述符的長度。
bDescriptorType: 描述符的類型(接口描述符為4)
bInterfaceNumber: 表示該接口的編號,用在配置有多個接口,每個接口有唯一放入編號,從0 開始編號。
bAlterateSetting:接口的備用編號,規則同上。一般不用
bNumEndpoint:該接口使用的端點數,不包括端點0。即如果為0 就只有控制端點。
bInterfaceClass:接口使用的類
bInterfaceSubClass:接口使用的子類
bInterfaceProtocol:接口使用的協議。三個一起定義了設備的功能,鼠標鍵盤就只需要改協議部分就可以。其他兩個都是HID類。
iInterface:接口字符串描述符的索引值。
USB端點描述符
域 | 大小(字節) | 偏移 |
bLenth | 1 | 0 |
bDescriptorType | 1 | 1 |
bEndpointAddress | 1 | 2 |
bmAttributes | 1 | 3 |
wMaxPackSize | 2 | 4 |
bInterval | 1 | 6 |
bLenth: 該描述符的長度(字節)
bDescriptorType: 該描述符的類型(0x05)
bEndpointAddress:端點的地址,D7表示端點的傳輸方向,為1則為輸入,為0則為輸出,D3-D0為端點號,其他位沒有用。
bmAttributes:一個字節的屬性描述字節,D1~D0表示端點傳輸類型,0 為控制傳輸,1為等時傳輸,2為批量傳輸,3為中斷傳輸。如果為等時傳輸,D3-D2表示等時傳輸的類型,0表示無同步,1為異步,2為適配,3為同步;D5-D4辨識用途,0為數據端點,1為反饋端點,2為暗反饋端點,3保留;D7-D6保留。但是如果不是同步傳輸則只用到D1-D0其他位全部保留。
wMaxPackSize:該端點支持的最大數據長度,對於低速和全速設備而言,D10-D0表示數據包最大長,其他位未用,對於高速設備D12-D11表示每個幀的附件傳送次數,具體參考USB標准協議。
bInterval:表示該端點的查詢時間,對於中斷傳輸表示查詢的幀間隔數;對於其他傳輸方式參考USB標准協議。
類特殊描述符
有些設備還需要有類特殊描述符,這里拿HID設備舉例,HID設備的特殊描述符如下
域 | 大小 | 偏移 | 說明 |
bLenth | 1 | 0 | 描述符長 |
bDescriptorType | 1 | 1 | 描述符類型 |
bcdHID | 2 | 2 | HID 協議版本 |
bCountryCode | 1 | 4 | 國家代碼 |
bNumDescriptors | 1 | 5 | 下級描述符數量 |
bDescriptorType | 1 | 6 | 下級描述符類型 |
bDescriptorLength | 2 | 7 | 下級描述符長度 |
bDescriptorType | 1 | 9 | 下級描述符的類型(可選) |
wDescriptorLength | 2 | 10 | 下級描述符的長度(可選) |
... | ... | ... | ... |
類比前面描述符的作用這里只需要記一下一下幾個字段的意義:
bcdHID:為 HID設備的版本,用BCD碼表示,兩個字節,如下表示版本為1.10
bCountryCode: 國家代碼(這個用在特殊情況下 比如鍵盤,美式鍵盤等)。
bNumDescriptors:下級描述符的數量,在HID設備中至少有一個是報告描述符。
bDescriptorType:HID報告描述符為0x22.
bDescriptorLength:對應描述符的大小。
因為下級描述符至少有一個因此,HID類描述至少是10個字節,底下就是一個HID描述符的例子。
0x09, /* bLength: HID Descriptor size */ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ 0x10, /* bcdHID: HID Class Spec release number */ 0x01, 0x00, /* bCountryCode: Hardware target country */ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ 0x22, /* bDescriptorType */ CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */ 0x00,
看了這么多,現在我對USB協議的理解是這樣的:USB設備可以理解為一個類,描述符就是這個類的屬性,而枚舉過程就是host主動請求調用,獲取屬性的方法,從而知道這個類的屬性,其余在主機和設備數據交換過程的處理細節就是設備類的方法,我們實現一個USB設備就是在定義設備屬性和定義方法接口的過程,只是定義屬性需要了解到以上USB標准中的這些規則(profile),同時枚舉過程的一些操作就是必須要實現的接口,其余的部分就要看我們的設備,設計出來支持的操作有哪些,選擇的實現了,好了暫時就這些,后面還有一部分概念需要學習,待續。。。
參考:《圈圈教你玩USB(第二版)》
2019-06-02 11:39:57