- 邏輯層次及描述符
邏輯上,usb包含設(shè)備(Device),配置(Configuration),接口(Interface)和端點(diǎn)(Endpoint)四個層次。設(shè)備通常有一個或多個配置,配置通常有一個或多個接口,接口有零個或多個端點(diǎn)(端點(diǎn)0應(yīng)該是沒有算進(jìn)去)。有多個配置的設(shè)備,任意時刻只能有一個配置處于激活狀態(tài)。在這四個層次之外,還有一個設(shè)置(setting),它與接口相關(guān),一個接口可以有多個設(shè)置(setting)。有多個設(shè)置(setting)的接口,任意時刻也只能有一個設(shè)置(setting)生效。
這四個層次都有相應(yīng)的描述符(另外一個常用的描述符是字符串描述符),它們都可以通過GET_DESCRIPTOR命令獲取。GET_DESCRIPTOR命令需要指定描述符類型,描述符索引等參數(shù)。需要注意的是,只能指定設(shè)備,配置和字符串三種描述符類型,而不能指定接口和端點(diǎn)這兩種描述符類型。這是因為在獲取配置描述符時,會把它包含的所有接口和端點(diǎn)描述符一次性獲取過來。因此,獲取配置描述符時,得到的內(nèi)容將是:配置描述符,接口0的描述符,接口0的端點(diǎn)描述符,接口1的描述符,接口1的端點(diǎn)描述符,直至接口n。另外,GET_DESCRIPTOR命令的描述符索引參數(shù),只對配置描述符和字符串描述符有效,分別用于獲取指定的配置描述符和字符串描述符,而對設(shè)備描述符無效(原因應(yīng)該是一個設(shè)備只有一個設(shè)備描述符)。
獲取設(shè)備描述符后,可以知道此設(shè)備支持幾個配置。獲取配置描述符后,可以得到此配置的編號(bConfigurationValue,應(yīng)該不是從0開始編號),還可以知道此配置支持幾個接口。解析接口描述符后,可以得到此接口的編號(bInterfaceNumber,從0開始編號,直至接口數(shù)目減1),還可以知道此接口支持幾個端點(diǎn)。注意,接口描述符里,并沒有說明此接口支持幾個設(shè)置(setting)。獲取配置描述符時,會一并獲取它支持的接口描述符,如果獲取到相同編號(bInterfaceNumber)的多個接口描述符,則是同一個接口的不同設(shè)置(setting),這些接口描述符的設(shè)置(setting)編號(bAlternateSetting,從0開始編號,直至設(shè)置(setting)數(shù)目減1)應(yīng)該不同。
- 描述符詳情
2.1 設(shè)備描述符
struct usb_device_descriptor {
__u8 bLength; // 18
__u8 bDescriptorType; // USB_DT_DEVICE,0x01
__le16 bcdUSB; // usb spec版本號,對應(yīng) sysfs 中的 version
__u8 bDeviceClass; // 見第3節(jié),“類別(Class)和協(xié)議(Protocol)”
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0; // 端點(diǎn)0一次可以處理的最大字節(jié)數(shù)
__le16 idVendor; // 廠商id
__le16 idProduct; // 產(chǎn)品id
__le16 bcdDevice; // 設(shè)備版本號
__u8 iManufacturer; // 廠商對應(yīng)的字符串描述符的索引值
__u8 iProduct; // 產(chǎn)品對應(yīng)的字符串描述符的索引值
__u8 iSerialNumber; // 序列號對應(yīng)的字符串描述符的索引值
__u8 bNumConfigurations; // 當(dāng)前速度模式下的配置數(shù)目(不是設(shè)備支持的所有配置數(shù)目)。
} __attribute__ ((packed));
2.2 配置描述符
struct usb_config_descriptor {
__u8 bLength; // 9
__u8 bDescriptorType; // USB_DT_CONFIG, 0x02
__le16 wTotalLength; // GET_DESCRIPTOR 標(biāo)準(zhǔn)請求返回的總長度
__u8 bNumInterfaces; // 此配置包含的接口數(shù)目
__u8 bConfigurationValue; // 可以看做是此配置的編號
__u8 iConfiguration; // 此配置對應(yīng)的字符串描述符的索引值
__u8 bmAttributes; // 此配置的特征。bit7必須為1,bit6:self powered. bit5:can wakeup. bit4:battery powered.
__u8 bMaxPower; // 表示此設(shè)備需要的最大電流,以2mA為單位
} __attribute__ ((packed));
在內(nèi)核usb代碼中,struct usb_device結(jié)構(gòu)體的config成員表示設(shè)備支持的所有配置,actconfig成員表示當(dāng)前激活的配置。在sysfs中,configuration(若不為空)就是當(dāng)前激活的配置的名稱(對應(yīng)配置描述符中的iConfiguration)。而sysfs中的bConfigurationValue與配置描述符中的bConfigurationValue對應(yīng),讀回就是當(dāng)前激活的配置的編號,寫入就是激活指定編號的配置。
2.3 接口描述符
struct usb_interface_descriptor {
__u8 bLength; // 9
__u8 bDescriptorType; // USB_DT_INTERFACE, 0x04
__u8 bInterfaceNumber; // 接口編號(zero-base)
__u8 bAlternateSetting; // 設(shè)置(setting)編號(zero-base)
__u8 bNumEndpoints; // 包含的端點(diǎn)數(shù)目(端點(diǎn)0不包含在內(nèi))
__u8 bInterfaceClass; // 見第3節(jié),“類別(Class)和協(xié)議(Protocol)”
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface; // 此接口對應(yīng)的字符串描述符的索引值
} __attribute__ ((packed));
有一種可能,配置中包含的接口的數(shù)目為1,但有多個接口描述符,應(yīng)該就是一個接口的不同設(shè)置(setting),因此有相同的接口編號(bInterfaceNumber),不同的設(shè)置(setting)(bAlternateSetting)編號。
2.4 端點(diǎn)描述符
struct usb_endpoint_descriptor {
__u8 bLength; // 7,9
__u8 bDescriptorType; // USB_DT_ENDPOINT, 0x05
__u8 bEndpointAddress; // bit0~3表示端點(diǎn)編號,bit8表示端點(diǎn)方向
__u8 bmAttributes; // 端點(diǎn)屬性
__le16 wMaxPacketSize; // 端點(diǎn)一次可以處理的最大字節(jié)數(shù)
__u8 bInterval; // 輪詢時間間隔
__u8 bRefresh; // 音頻相關(guān)
__u8 bSynchAddress; // 音頻相關(guān)
} __attribute__ ((packed));
- 類別(Class)和協(xié)議(Protocol)
類別(Class)是針對設(shè)備和接口定義的,有一些類別(Class)僅針對設(shè)備,有一些類別(Class)僅針對接口,還有一些類別(Class)對設(shè)備和接口都有效。如下圖所示:

而子類別(SubClass)和協(xié)議(Protocol)就根據(jù)類別(Class)的不同而不同了。
以常見的HID為例,它對應(yīng)的子類別(SubClass)和協(xié)議(Protocol)如下圖所示:

而Mass Storage對應(yīng)的則是:

上述信息參考如下網(wǎng)址:
https://www.usb.org/defined-class-codes
https://www.usb.org/sites/default/files/hid1_11.pdf
https://www.usb.org/sites/default/files/Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf
更多信息,可以在下面的網(wǎng)址中搜索相關(guān)文檔:
https://www.usb.org/documents?search=spec&items_per_page=50