USB子系統架構
1 Linux USB驅動層次
Linux USB驅動總體結構:
從主機側看,在Linux驅動中,處於USB驅動最底層的是USB主機控制器硬件,在其上運行的是USB主機控制器驅動,在主機控制器上的為USB核心層,再上層為USB設備驅動層(插入主機上的U盤、鼠標、USB轉串口等設備驅動)。因此,在主機側的層次結構中,要實現的USB驅動包括兩類:USB主機控制器驅動和USB設備驅動,前者控制插入其中的USB設備,後者控制USB設備如何與主機通信。USB核心負責USB驅動管理和協議處理的主要工作,通過定義一些數據結構、宏和功能函數,向上為設備驅動提供編程接口,向下為USB主機控制器驅動提供編程接口。
Linux內核USB設備側驅動程序分為3個層次:UDC驅動程序、Gadget API和Gadget驅動程序。UDC驅動程序直接訪問硬件,控制USB設備和主機間的底層通信,向上層提供與硬件相關操作的回調函數。當前Gadget API是UDC驅動程序回調函數的簡單包裝。Gadget驅動程序具體控制USB設備功能的實現,使設備表現出“網絡連接”、“打印機”或“USB Mass Storage”等特性,它使用Gadget API控制UDC實現上述功能。
2 設備、配置、接口、端點
在USB設備的邏輯組織中,包含設備、配置、接口和端點4個層次。
- 設備通常有一個或多個配置;
- 配置通常有一個或多個接口;
- 接口通常有一個或多個設置;
- 接口有零個或多個端點。
(1)設備描述符:在Linux內核中,USB設備用usb_device結構體來描述,USB設備描述符定義為usb_device_descriptor結構體。
1 /* include/uapi/linux/usb/ch9.h */ 2 struct usb_device_descriptor { 3 __u8 bLength; // 描述符長度 4 __u8 bDescriptorType; // 描述符類型編號 5 6 __le16 bcdUSB; // USB版本號 7 __u8 bDeviceClass; //USB分配的設備類code 8 __u8 bDeviceSubClass; // USB分配的子類code 9 __u8 bDeviceProtocol; // USB分配的協議code 10 __u8 bMaxPacketSize0; // endpoint0最大包大小 11 __le16 idVendor; // 廠商編號 12 __le16 idProduct; // 產品編號 13 __le16 bcdDevice; // 設備出廠編號 14 __u8 iManufacturer; // 描述廠商字符串的索引 15 __u8 iProduct; // 描述產品字符串的索引 16 __u8 iSerialNumber; // 描述設備序列號字符串的索引 17 __u8 bNumConfigurations; // 可能的配置數量 18 } __attribute__ ((packed));
(2)配置描述符:USB配置在內核中使用usb_host_config結構體描述,而USB配置描述符定義為結構體usb_config_descriptor。
1 /* include/uapi/linux/usb/ch9.h */ 2 struct usb_config_descriptor { 3 __u8 bLength; // 描述符長度 4 __u8 bDescriptorType; // 描述符類型編號 5 6 __le16 wTotalLength; // 配置所返回的所有數據的大小 7 __u8 bNumInterfaces; // 配置所支持的接口數 8 __u8 bConfigurationValue; // Set_Configuration命令需要的參數值 9 __u8 iConfiguration; // 描述該配置的字符串的索引值 10 __u8 bmAttributes; // 供電模式的選擇 11 __u8 bMaxPower; // 設備從總線提取的最大電流 12 } __attribute__ ((packed));
(3)接口描述符:USB接口在內核中使用usb_interface結構體描述,而USB接口描述符定義為結構體usb_interface_descriptor。
1 /* include/uapi/linux/usb/ch9.h */ 2 struct usb_interface_descriptor { 3 __u8 bLength; // 描述符長度 4 __u8 bDescriptorType; // 描述符類型編號 5 6 __u8 bInterfaceNumber; // 接口的編號 7 __u8 bAlternateSetting; // 備用的接口描述符編號 8 __u8 bNumEndpoints; // 該接口使用的端點數,不包括端點0 9 __u8 bInterfaceClass; // 接口類型 10 __u8 bInterfaceSubClass; // 接口子類型 11 __u8 bInterfaceProtocol; // 接口所遵循的協議 12 __u8 iInterface; // 描述該接口的字符串索引值 13 } __attribute__ ((packed));
(4)端點描述符:USB端點使用usb_host_endpoint結構體來描述,而USB端點描述符定義為usb_endpoint_descriptor結構體。
1 /* include/uapi/linux/usb/ch9.h */ 2 struct usb_endpoint_descriptor { 3 __u8 bLength; // 描述符長度 4 __u8 bDescriptorType; // 描述符類型 5 6 __u8 bEndpointAddress; // 端點地址,0~3位是端點號,第7位是方向(0為輸出,1為輸出) 7 __u8 bmAttributes; // 端點屬性:bit[0:1]的值為00表示控制,為01表示同步,為02表示批量,為03表示中斷 8 __le16 wMaxPacketSize; // 本端點接收或發送的最大信息包的大小 9 __u8 bInterval; // 輪詢數據傳送端點的時間間隔 10 11 __u8 bRefresh; 12 __u8 bSynchAddress; 13 } __attribute__ ((packed));
(5)字符串描述符。
1 /* include/uapi/linux/usb/ch9.h */ 2 struct usb_string_descriptor { 3 __u8 bLength; // 描述符長度 4 __u8 bDescriptorType; // 描述符類型 5 6 __le16 wData[1]; // 以UTF-16LE編碼 7 } __attribute__ ((packed));
USB子系統架構