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));