1.usb几个结构体总结
(1)usb_bus_type usb总线类型结构体
drivers/usb/core/driver.c
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
};
(2) usb_interface 接口是设备的接口
struct usb_interface
{
struct usb_host_interface *altsetting;
struct usb_host_interface *cur_altsetting; /* the currently active alternate setting *
}
(3) usb_host_interface 设置是接口的设置
struct usb_host_interface {
struct usb_interface_descriptor desc; //接口描述符
struct usb_host_endpoint *endpoint; //端点结构体
}
(4)usb_host_endpoint 端点结构体 usb数据传输的终点
{
struct usb_endpoint_descriptor desc; //端点描述符
}
(5)usb_device usb设备结构体
struct usb_device
{
struct usb_bus *bus; //总线
struct usb_host_endpoint ep0; //端点0
struct usb_device_descriptor descriptor; //设备描述符
struct usb_host_config *config; //设备拥有的所有配置
struct usb_host_config *actconfig; // 设备当前的配置
struct usb_host_endpoint *ep_in[16];
struct usb_host_endpoint *ep_out[16]; //一个设备在高速模式下最多有15个 ep_in和ep_out端点
}
(6)usb_host_config usb设备的配置结构体
struct usb_host_config
{
struct usb_config_descriptor desc; //usb配置描述符
}
2.USB描述符
USB描述符信息存储在USB设备中,在枚举过程中,USB主机会向USB设备发送GetDescriptor请求,USB设备在收到这个请求之后,会将USB描述符信息返回给USB主机,USB主机分析返回来的数据,判断出该设备是哪一种USB设备,建立相应的数据链接通道。
通用的USB描述符信息包括设备描述符、配置描述符、接口描述符和端点描述符,具体不同的USB设备还包括其它类型的描述符,例如,USB鼠标、键盘还包括HID描述符和报告描述符,还有可能包括字符串描述符。
(1)设备描述符 struct usb_device_descriptor
(2)配置描述符 struct usb_config_descriptor
(3)接口描述符 struct usb_interface_descriptor
(4)端点描述符 struct usb_endpoint_descriptor
(1)设备描述符 struct usb_device_descriptor
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
#define USB_DT_DEVICE_SIZE 18
我们的usb设备描述符的信息:
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x18d1 Google Inc.
idProduct 0xd002
bcdDevice ff.ff
iManufacturer 5 Android
iProduct 6 Android
iSerial 7 ingenic-halley2_v10-6
bNumConfigurations 1
bLength: 描述符的长度,设备描述符的长度为18个字节。
bDescriptorType: 描述符的类型,设备描述符的类型为0x01。
bcdUSB: USB设备所遵循的协议版本号,例如2.0协议为0x0200。
bDeviceClass: USB设备类代码,由USB-IF分配,如果该字段为0x00,表示由接口描述符来指定(有可能该USB设备是一个复合设备,USB设备的各个接口相互独立,分别属于不同的设备类)。如果是0x01~0xfe,表示为USB-IF定义的设备类,例如0x03为HID设备,0x09为HUB设备。如果是0xff,表示由厂商自定义设备类型。
bDeviceSubClass: USB子类代码,由USB-IF分配,如果bDeviceClass为0x00,那么该字段也必须为 0x00,其它情况可以参考USB关于对于USB Device Class的定义。
bDeviceProtocol: 协议代码,由USB-IF分配,如果bDeviceClass和bDeviceSubClass定义为0x00,那么该字段也必须为0x00。
bMaxPacketSize0: 端点0最大数据包长度,必须为8、16、32和64。
idVendor: 厂商ID,由USB-IF分配,需要向USB-IF组织申请。
idProduct: 产品ID,由厂商指定。
bcdDevice: 设备序列号,由厂商自行设置。
iManufacturer: 用于描述厂商的字符串描述符索引。
iProduct: 用于描述产品的字符串描述符索引。
iSerialNumber: 用于描述产品序列号的字符串描述符索引,注意,所有的字符串描述符是可选的,如果没有字符串描述符,指定这些索引为0x00。
bNumConfigurations:配置描述符数量。
(2)配置描述符 struct usb_config_descriptor
一个USB设备只有一个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
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 55
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 500mA
bLength: 配置描述符长度,配置描述符长度为9字节大小。
bDescriptorType: 描述符类型,配置描述符类型为0x02。
wTotalLength: 配置描述符信息总的大小,包括接口描述符、端点描述符等等。
bNumInterfaces: USB接口数量。
bConfigurationValue: 当使用SetConfiguration和GetConfiguration请求时所指定的配置索引值。
iConfiguration: 描述配置的字符串描述符索引。
bmAttributes: 供电配置,位详细定义如下:
D7 保留,必须置1
D6 自供电模式
D5 远程唤醒
D4~D0 保留
bMaxPower: 最大功耗,以2mA为单位,例如0x32为50*2=100mA。
(3)接口描述符 struct usb_interface_descriptor
一个配置中可以有一个或多个接口,一个接口中有0个或多个端点,接口描述符和端点描述符不能直接通过GetDescriptor请求返回,必须连同配置描述符一起返回
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
Interface Descriptor:(第一个接口描述符)
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2 两个端点描述符
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk-Only
iInterface 4 Mass Storage
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Interface Descriptor:
bLength: 描述符长度,接口描述符长度为9个字节。
bDescriptorType: 描述符类型,接口描述符的类型为0x04。
bInterfaceNumber: 该接口编号,接口编号从0开始分配,当一个配置有多个接口时,就用该字段来区分不同的接口。
bAlternateSetting:
bNumEndpoints: 端点数量,不包括端点0。
bInterfaceClass
bInterfaceSubClass
bInterfaceProtocol: 和设备描述符中的bDeviceClass、bDeviceSubClass、bDeviceProtocol类似。
iInterface: 描述该接口的字符串描述符索引
(4)端点描述符 struct usb_endpoint_descriptor
端点0没有端点描述符
/* USB_DT_ENDPOINT: Endpoint descriptor */
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 */
Interface Descriptor:(第二个接口描述符)
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 66
bInterfaceProtocol 1
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
bLength: 描述符长度,这里有两个值如果是audio设备的端点,那么端点描述符长度就为9个字节,对于其它设备端点,端点描述符长度就为7个字节。
bDescriptorType: 描述符类型,端点描述符类型为0x05。
bEndpointAddress: 端点地址,详细定义如下:
D7 端点方向
0 OUT端点
1 IN端点
D6~D4 保留
D3~D0 端点编号
bmAttributes: 端点类型,详细定义如下:
D5~D4 用途
00 数据端点
01 反馈端点
10 隐式反馈数据端点
11 保留
D3~D2 同步类型
00 非同步
01 异步
10 自适应
11 同步
D1~D0 传输类型
00 控制传输
01 同步传输
10 块传输
11 中断传输
如果该端点不是同步端点,D5~D2保留且必须置0。
wMaxPacketSize: 端点所支持最大数据包的长度,详细定义如下:
D10~D0 最大数据包长度
D12~D11
其余位保留且必须置0。
bInterval:端点数据传输的访问时间间隔。对于全速/低速的中断端点,取值范围为 1~255,对于高速中断端点,取值范围为1~16,详细定义可以参考USB协议。
(5)HID描述符
struct hid_class_descriptor {
__u8 bDescriptorType;
__le16 wDescriptorLength;
} __attribute__ ((packed));
struct hid_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdHID;
__u8 bCountryCode;
__u8 bNumDescriptors;
struct hid_class_descriptor desc[1];
} __attribute__ ((packed));
bLength: 描述符长度。
bDescriptorType:描述符类型,HID描述符的类型为0x21。
bcdHID: 所遵循的HID协议版本。
bCountryCode: 国家代码。
bNumDescriptors: 下级描述符数量,通常至少需要一个报告描述符。
bDescriptorType: 下级描述符类型,例如报告描述符。
wDescriptorLength: 下级描述符长度。