USB裝置的列舉過程分析——資料結構先行
USB列舉是host端為了配置(載入合適的驅動)device進行的一個重要配置,如果列舉成功,那麼裝置正常工作的可能性約為90%,是USB驅動程式中重要的一項配置。主要進行的操作就是獲取配置描述符,解析配置描述符、解析埠描述符;簡而言之就是從device端獲取device效能和配置。
先介紹一下列舉過程中涉及的結構體和成員:
第一個 usb 配置描述符
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
#define USB_DT_CONFIG_SIZE 9
bLength: 表示usb 配置描述符所佔位元組長度,一般為 9 bytes(標準usb協議),也可能更多,根據usb裝置廠商而定
bDdescriptorType: 描述符的型別,表示這是配置描述符,固定為0x02
wTotallLength: 表示所有配置描述符所佔位元組數的大小,即 配置描述符 + 介面描述符 + 端點描述符 的總位元組數
bNumInterfaces:該配置下有多少個介面數,一種配置(config)就代表一種功能(如 U盤),一個功能可能有多個介面
bConfigurationValue: 當前配置
iConfiguration:描述配置的字串索引
bmAttributes:供電配置,其bit位定義如下:
D7 保留,必須 為 1
D6 自供電模式
D5 遠端喚醒
D4~D0 保留
bMaxPower:最大功耗,以2mA為步進,如 0x05 表示的功耗為 5 * 2 = 10mA
第二個 介面描述符
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
#define USB_DT_INTERFACE_SIZE 9
bLength: 表示usb 端點描述符所佔位元組長度,一般為 9 bytes(標準usb協議),也可能更多,根據usb裝置廠商而定
bDdescriptorType: 描述符的型別,表示這是配置描述符,固定為0x04
bInerfaceNumber:介面編號,一配置下可能有多個介面,這種情況下一般是從0開始編號
bAlternateSetting:當前選中的設定
bNumEndpoints:該介面下的端點數目,一個介面可能有多個端點
bInterfaceclass、bInterfacesubclass、bInterfaceProtocol分別表示介面的類、子類及所支援的協議。
iInterface:該介面的字串索引值
第三個 埠描述符
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
bLength: 表示usb 端點描述符所佔位元組長度,
bDdescriptorType: 描述符的型別,表示這是配置描述符,固定為0x05
bEndpointAddress:端點的地址,根據協議 bit7 表示方向,1為IN,0為OUT,bit6~bit4 保留,bit3~bit0 為端點編號
bmAttributes:表示端點的屬性,根據協議,其定義為:
bit0~bit1 傳輸型別 | 0 | 控制傳輸 | bit2~bit3 同步型別 | 0 | 不同步 | bit4~bit5 端點型別 | 0 | 資料端點 |
1 | 同步傳輸 | 1 | 非同步 | 1 | 反饋端點 | |||
2 | 塊傳輸 | 2 | 自適應 | 2 | 隱式反饋端點 | |||
3 | 中斷傳輸 | 3 | 同步 | 3 | 保留 |
wPackageSize:該端點所能處理最多位元組數的資料
bInterval: 端點訪問時間間隔
接了下來兩個是和音訊相關額外的描述符。
在解析描述符時,還有兩個常用的 結構體,
struct usb_host_interface {
struct usb_interface_descriptor desc;
int extralen;
unsigned char *extra; /* Extra descriptors */
/* array of desc.bNumEndpoints endpoints associated with this
* interface setting. these will be in no particular order.
*/
struct usb_host_endpoint *endpoint;
char *string; /* iInterface string, if present */
};
該結構體表示在host端呈現出的介面描述符。
struct usb_descriptor_header {
__u8 bLength;
__u8 bDescriptorType;
} __attribute__ ((packed));
常用來獲取型別和長度,節約記憶體。
相關文章
- 列舉python常用的資料結構Python資料結構
- 詳細分析棧和佇列的資料結構的實現過程(Java 實現)佇列資料結構Java
- 詳細分析連結串列的資料結構的實現過程(Java 實現)資料結構Java
- 資料結構複習-01enum列舉型別資料結構型別
- USB裝置在端點4~7互動資料
- 資料需求分析過程
- ubuntu 為USB串列埠繫結固定的裝置名Ubuntu串列埠
- 資料結構與演算法分析——佇列資料結構演算法佇列
- Partial類、列舉、結構體結構體
- 結構體,列舉,聯合結構體
- 資料結構 - 佇列資料結構佇列
- 資料結構 - 陣列資料結構陣列
- 資料結構-陣列資料結構陣列
- 資料結構-佇列資料結構佇列
- 【資料結構-----佇列】資料結構佇列
- 大資料分析過程是如何的大資料
- 資料結構--單連結串列(通過陣列實現)資料結構陣列
- 分析oc物件的記憶體結構及其建立過程物件記憶體
- 資料結構-佇列、棧資料結構佇列
- 資料結構2——陣列資料結構陣列
- 資料結構之「佇列」資料結構佇列
- 資料結構-佇列-樹資料結構佇列
- 資料結構之「陣列」資料結構陣列
- 資料結構之陣列資料結構陣列
- Unbound資料結構分析資料結構
- LinkedList 資料結構分析資料結構
- ArrayList 資料結構分析資料結構
- Linux 4.x MTD原始碼分析-cfi-flash裝置probe過程分析Linux原始碼
- MongoDB的選舉過程MongoDB
- Slice在使用過程中需要懂的一些資料結構資料結構
- 大資料開發過程中Kafka日誌結構解析大資料Kafka
- redis資料結構原始碼閱讀——字串編碼過程Redis資料結構原始碼字串編碼
- 列舉直播搭建過程中SDK的含義及優勢
- 資料結構——樹狀陣列資料結構陣列
- C++資料結構-佇列C++資料結構佇列
- JavaScript資料結構之-佇列JavaScript資料結構佇列
- 資料結構之佇列(Queue)資料結構佇列
- 資料結構(棧和佇列)資料結構佇列