您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

usb设备结构及描述符拓扑

1、usb 设备

1.1 usb_device

// 拓扑重点关注
struct usb_device {
    struct usb_host_endpoint ep0;   	//端点0 的特殊地位决定了它必将受到特殊的待遇,在struct usb_device 对象产生的时候它就要初始化
    struct usb_device_descriptor descriptor;	/* Descriptor 设备描述符,此结构体的bMaxPacketSize0 filed保存了端点0的maximum packet size*/
    
    struct usb_host_config *config; 			//设备拥有的所有配置
    struct usb_host_config *actconfig;			//设备正在使用的配置
    
    struct usb_host_endpoint *ep_in[16];		//ep_in[16],ep_out[16],除了端点0,一个设备即使在高速模式下也最多只能再有15个IN端点和15个OUT端点,端点0太特殊了
    struct usb_host_endpoint *ep_out[16];		//对应的管道是Message管道,又能进又能出的那种,所以这里的ep_in和ep_out数组都有16个值
};

// 完整解释
struct usb_device {
    int devnum;         				//devnum 只是usb设备在一条usb总线上的编号.一条usb_bus_type类型的总线上最多可以连上128个设备
    char devpath [16];   				/* Use in messages: /port/port/...*/  //对于root hub.会将dev->devpath[0]=’0’
    enum usb_device_state   state;  	//设备的状态Attached,Powered,Default,Address,Configured,Suspended;
										//Attached 表示设备已经连接到usb接口上了,是hub检测到设备时的初始状态。那么这里所谓的USB_STATE_NOTATTACHED就是表示设备并没有Attached。
										//Address 状态表示主机分配了一个唯一的地址给设备,此时设备可以使用缺省管道响应主机的请求
										//Configured 状态表示设备已经被主机配置过了,也就是协议里说的处理了一个带有非0值的SetConfiguration()请求,此时主机可以使用设备提供的所有功能
										//Suspended 挂起状态,为了省电,设备在指定的时间内,3ms吧,如果没有发生总线传输,就要进入挂起状态。此时,usb设备要自己维护包括地址、配置在内的信息             

    enum usb_device_speed   speed;  	/* high/full/low (or error) */
    struct usb_tt   *tt;            	//如果一个高速设备里有这么一个TT,那么就可以连接低速/全速设备,如不然,那低速/全速设备没法用,只能连接到OHCI/UHCI那边出来的hub口里。
    int             ttport;         	//如果一个高速设备里有这么一个TT,那么就可以连接低速/全速设备,如不然,那低速/全速设备没法用,只能连接到OHCI/UHCI那边出来的hub口里。

    unsigned int toggle[2];         	/* one bit for each endpoint     //他实际上就是一个位图.IN方向的是toggle[0].OUT方向的是toggle[1].其实,这个数组中的每一位表示ep的toggle值
                                             * ([0] = IN, [1] = OUT) 它里面的每一位表示的就是每个端点当前发送或接收的数据包是DATA0还是DATA1*/
    
    struct usb_device *parent;      	/* our hub, unless we're the root */
										//USB设备是从Root Hub开始,一个一个往外面连的,比如Root Hub有4个口,每个口连一个USB设备,比如其中有一个是Hub,那么这个Hub有可以继续有多个口,于是一级一级的往下连,
										//最终连成了一棵树。
    struct usb_bus *bus;            	/* Bus we're part of 设备所在的总线*/
    struct usb_host_endpoint ep0;   	//端点0 的特殊地位决定了她必将受到特殊的待遇,在struct usb_device 对象产生的时候它就要初始化

    struct device dev;              	/* Generic device interface 嵌入到struct usb_device结构里的struct device结构*/

    struct usb_device_descriptor descriptor;	/* Descriptor 设备描述符,此结构体的bMaxPacketSize0 filed保存了端点0的maximum packet size*/
    struct usb_host_config *config; 			//设备拥有的所有配置

    struct usb_host_config *actconfig;			//设备正在使用的配置
    struct usb_host_endpoint *ep_in[16];		//ep_in[16],ep_out[16],除了端点0,一个设备即使在高速模式下也最多只能再有15个IN端点和15个OUT端点,端点0太特殊了,
    struct usb_host_endpoint *ep_out[16];		//对应的管道是Message管道,又能进又能出特能屈能伸的那种,所以这里的ep_in和ep_out数组都有16个值

    unsigned short bus_mA;          /* Current available from the bus 这个值是在host controller的驱动程序中设置的,通常来讲,计算机的usb端口可以提供500mA的电流*/
    u8 portnum;                     //不管是root hub还是一般的hub,你的USB设备总归要插在一个hub的端口上才能用,portnum就是那个端口号。
    u8 level;                       //层次,也可以说是级别,表征usb设备树的级连关系。Root Hub的level当然就是0,其下面一层就是level 1,再下面一层就是level 2,依此类推


    /* static strings from the device */
    char *product;                  /* iProduct string, if present */
    char *manufacturer;             /* iManufacturer string, if present */
    char *serial;                   /* iSerialNumber string, if present */
                                    //分别用来保存产品、厂商和序列号对应的字符串描述符信息

    int maxchild;                   /* Number of ports if hub */
    struct usb_device *children[USB_MAXCHILDREN];

    int pm_usage_cnt;               /* usage counter for autosuspend */
    u32 quirks;                     //quirk就是用来判断这些有毛病的产品啥毛病的

};

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

2、usb 配置

2.1 usb_host_config

struct usb_host_config {
	struct usb_config_descriptor	desc;		//配置描述符

	char *string;		/* iConfiguration string, if present */

	/* List of any Interface Association Descriptors in this
	 * configuration. */
	struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];

	/* the interfaces associated with this configuration,
	 * stored in no particular order */
	struct usb_interface *interface[USB_MAXINTERFACES];		//包含的接口

	/* Interface information available even when this is not the
	 * active configuration */
	struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];

	unsigned char *extra;   /* Extra descriptors */
	int extralen;
};

2.2 usb_config_descriptor

struct usb_config_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__le16 wTotalLength;
	__u8  bNumInterfaces;
	__u8  bConfigurationValue;
	__u8  iConfiguration;
	__u8  bmAttributes;
	__u8  bMaxPower;
} __attribute__ ((packed));

3、usb 接口

3.1 usb_interface

struct usb_interface {
	struct usb_host_interface *altsetting;  		// 当前接口的可选设置

	struct usb_host_interface *cur_altsetting;  	// 当前接口使用的设置
 
	unsigned num_altsetting;  						// 当前接口具有的可选设置总数

	int minor;   	// 当前接口的在主设备号为USB_MAJOR时的子设备号,minor只在USB_MAJOR起作用时起作用。 
					//usb 设备没有与其它任何子系统关联,就需要在对应驱动的 probe 函数里使用 usb_register_dev 函数来注册并获得主设备号USB_MAJOR。
					//如果usb设备关联了其它子系统,则需要在对应驱动的probe函数里使用相应的注册函数,USB_MAJOR 也就该干吗干吗去,用不着它了。
					//比如,usb 键盘关联了 input 子系统,驱动对应 drivers/hid/usbhid 目录下的 usbkbd.c文件,
					//在它的probe函数里可以看到使用了input_register_device 来注册一个输入设备。

	enum usb_interface_condition condition; 	/* state of binding */ // 当前接口 所处的连接绑定阶段

	struct device dev; 							/* interface specific device info */ // linux设备模型里的device嵌在这儿的对象
	struct device *usb_dev;  					// 当接口使用USB_MAJOR作为主设备号时,usb_dev才会用到, usb_register_dev和usb_deregister_dev使用这个结构体,usb_dev指向的
												//就是usb_register_dev函数里创建的usb class device。
}

3.2 usb_host_interface

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 */
};

3.3 usb_interface_descriptor

struct usb_interface_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bInterfaceNumber;
	__u8  bAlternateSetting;
	__u8  bNumEndpoints;
	__u8  bInterfaceClass;
	__u8  bInterfaceSubClass;
	__u8  bInterfaceProtocol;
	__u8  iInterface;
} __attribute__ ((packed));

4、usb 端点

4.1 usb_host_endpoint

struct usb_host_endpoint {
	struct usb_endpoint_descriptor		desc;
	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
	struct usb_ssp_isoc_ep_comp_descriptor	ssp_isoc_ep_comp;
	struct list_head		urb_list;
	void				*hcpriv;
	struct ep_device		*ep_dev;	/* For sysfs info */

	unsigned char *extra;   /* Extra descriptors */
	int extralen;
	int enabled;
	int streams;
};

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

分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进