博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
USB_4大描述符
阅读量:5774 次
发布时间:2019-06-18

本文共 6965 字,大约阅读时间需要 23 分钟。

 本文来自CSDN博客,转载请标明出处:


在USB描述符中,从上到下分为四个层次:

USB设备描述符(usb_device_descriptor)、

USB配置描述符(usb_config_descriptor)、

USB接口描述符(usb_interface_descriptor)、

USB端点描述符(usb_endpoint_descriptor)、

一个设置描述符可以有多个配置描述符

一个配置描述符可以有多个接口描述符(比如声卡驱动,就有两个接口:录音接口和播放接口)

一个接口描述符可以有多个端点描述符

 

1.其中USB设备描述符结构体如下所示:

struct usb_device_descriptor { __u8  bLength;                          //本描述符的size __u8  bDescriptorType;              //描述符的类型,这里是设备描述符DEVICE __u16 bcdUSB;                           //指明usb的版本,比如usb2.0 __u8  bDeviceClass;                 //类 __u8  bDeviceSubClass;             //子类 __u8  bDeviceProtocol;              //指定协议 __u8  bMaxPacketSize0;            //端点0对应的最大包大小 __u16 idVendor;                         //厂家ID __u16 idProduct;                        //产品ID __u16 bcdDevice;                       //设备的发布号 __u8  iManufacturer;                 //字符串描述符中厂家ID的索引 __u8  iProduct;                         //字符串描述符中产品ID的索引 __u8  iSerialNumber;                 //字符串描述符中设备序列号的索引 __u8  bNumConfigurations;              //配置描述符的个数,表示有多少个配置描述符} __attribute__ ((packed));

USB设备描述符位于USB设备结构体usb_device中的成员descriptor

同样地,配置、接口、端点描述符也是位于USB配置、接口、端点结构体中,不过这3个对于我们写驱动的不是很常用

usb_device结构体如下所示:

struct usb_device {   int devnum;           //设备号,是在USB总线的地址   char devpath [16];       //用于消息的设备ID字符串   enum usb_device_state state; //设备状态:已配置、未连接等等   enum usb_device_speed speed; //设备速度:高速、全速、低速或错误     struct usb_tt *tt;       //处理传输者信息;用于低速、全速设备和高速HUB   int ttport;           //位于tt HUB的设备口     unsigned int toggle[2];    //每个端点的占一位,表明端点的方向([0] = IN, [1] = OUT)     struct usb_device *parent;  //上一级HUB指针   struct usb_bus *bus;       //总线指针   struct usb_host_endpoint ep0; //端点0数据   struct device dev;         //一般的设备接口数据结构    struct usb_device_descriptor descriptor; //USB设备描述符,   struct usb_host_config *config;       //设备的所有配置结构体,配置结构体里包含了配置描述符   struct usb_host_config *actconfig;     //被激活的设备配置   struct usb_host_endpoint *ep_in[16];     //输入端点数组   struct usb_host_endpoint *ep_out[16];     //输出端点数组     char **rawdescriptors;             //每个配置的raw描述符     unsigned short bus_mA;         //可使用的总线电流   u8 portnum;               //父端口号   u8 level;                //USB HUB的层数     unsigned can_submit:1;         //URB可被提交标志   unsigned discon_suspended:1;      //暂停时断开标志   unsigned persist_enabled:1;       //USB_PERSIST使能标志   unsigned have_langid:1;         //string_langid存在标志   unsigned authorized:1;    unsigned authenticated:1;   unsigned wusb:1;             //无线USB标志   int string_langid;             //字符串语言ID     /* static strings from the device */ //设备的静态字符串   char *product;               //产品名   char *manufacturer;             //厂商名   char *serial;                 //产品串号     struct list_head filelist;         //此设备打开的usbfs文件  #ifdef CONFIG_USB_DEVICE_CLASS   struct device *usb_classdev;       //用户空间访问的为usbfs设备创建的USB类设备  #endif  #ifdef CONFIG_USB_DEVICEFS   struct dentry *usbfs_dentry;        //设备的usbfs入口  #endif     int maxchild;                     //(若为HUB)接口数   struct usb_device *children[USB_MAXCHILDREN];//连接在这个HUB上的子设备   int pm_usage_cnt;                 //自动挂起的使用计数   u32 quirks;    atomic_t urbnum;                   //这个设备所提交的URB计数     unsigned long active_duration;         //激活后使用计时  #ifdef CONFIG_PM                 //电源管理相关   struct delayed_work autosuspend;       //自动挂起的延时   struct work_struct autoresume;       //(中断的)自动唤醒需求   struct mutex pm_mutex;           //PM的互斥锁      unsigned long last_busy;         //最后使用的时间   int autosuspend_delay;    unsigned long connect_time;       //第一次连接的时间     unsigned auto_pm:1;           //自动挂起/唤醒   unsigned do_remote_wakeup:1;     //远程唤醒   unsigned reset_resume:1;       //使用复位替代唤醒   unsigned autosuspend_disabled:1;   //挂起关闭   unsigned autoresume_disabled:1;   //唤醒关闭   unsigned skip_sys_resume:1;     //跳过下个系统唤醒  #endif   struct wusb_dev *wusb_dev;     //(如果为无线USB)连接到WUSB特定的数据结构  };

 

2. 配置描述符结构如下所示:

struct usb_config_descriptor {     __u8  bLength;                          //描述符的长度  __u8  bDescriptorType;              //描述符类型的编号  __le16 wTotalLength;                        //配置 所返回的所有数据的大小  __u8  bNumInterfaces;              //配置 所支持的接口个数, 表示有多少个接口描述符  __u8  bConfigurationValue;        //Set_Configuration命令需要的参数值  __u8  iConfiguration;                        //描述该配置的字符串的索引值  __u8  bmAttributes;                         //供电模式的选择  __u8  bMaxPower;                    //设备从总线提取的最大电流 } __attribute__ ((packed));

 

3.接口描述符结构如下所示: 

USB接口只处理一种USB逻辑连接。一个USB接口代表一个逻辑上的设备,比如声卡驱动,就有两个接口:录音接口和播放接口

这可以在windows系统中看出,有时插入一个USB设备后,系统会识别出多个设备,并安装相应多个的驱动。

struct usb_interface_descriptor {    __u8  bLength;                          //描述符的长度  __u8  bDescriptorType;              //描述符类型的编号  __u8  bInterfaceNumber;           //接口的编号  __u8  bAlternateSetting;            //备用的接口描述符编号,提供不同质量的服务参数.  __u8  bNumEndpoints;              //要使用的端点个数(不包括端点0), 表示有多少个端点描述符,比如鼠标就只有一个端点  __u8  bInterfaceClass;              //接口类型,与驱动的id_table   __u8  bInterfaceSubClass;                 //接口子类型  __u8  bInterfaceProtocol;                 //接口所遵循的协议  __u8  iInterface;                        //描述该接口的字符串索引值 } __attribute__ ((packed)

 它位于usb_interface->cur_altsetting->desc 这个成员结构体里,

 usb_interface结构体如下所示:

struct usb_interface {  struct usb_host_interface *altsetting; /* 包含所有可用于该接口的可选设置的接口结构数组。每个 struct usb_host_interface 包含一套端点配置(即struct usb_host_endpoint结构所定义的端点配置。这些接口结构没有特别的顺序。*/   struct usb_host_interface *cur_altsetting; /* 指向altsetting内部的指针,表示当前激活的接口配置*/     unsigned num_altsetting; /* 可选设置的数量*/   /* If there is an interface association descriptor then it will list the associated interfaces */  struct usb_interface_assoc_descriptor *intf_assoc;     int minor; /* 如果绑定到这个接口的 USB 驱动使用 USB 主设备号, 这个变量包含由 USB 核心分配给接口的次设备号. 这只在一个成功的调用 usb_register_dev后才有效。*/   ... ...}

cur_altsetting成员的结构体是usb_host_interface,如下: 

struct usb_host_interface {    struct usb_interface_descriptor desc;   //当前被激活的接口描述符    struct usb_host_endpoint *endpoint;   /* 这个接口的所有端点结构体的联合数组*/    char *string;                 /* 接口描述字符串 */    unsigned char *extra;           /* 额外的描述符 */    int extralen;};

 

4.端点描述符结构如下所示:

struct usb_endpoint_descriptor {__u8  bLength;                          //描述符的长度__u8  bDescriptorType;              //描述符类型的编号__u8  bEndpointAddress;              //端点编号,比如端点1,就是1__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));

 比如端点0,就位于usb_interface->cur_altsetting->desc->endpoint[0].desc

其中endpoint的结构体为usb_host_endpoint,如下所示:

struct usb_host_endpoint {struct usb_endpoint_descriptor desc; //端点描述符struct usb_ss_ep_comp_descriptor ss_ep_comp;//超快速端点描述符struct list_head urb_list; //本端口对应的urb链表void *hcpriv;struct ep_device *ep_dev; /* For sysfs info */unsigned char *extra; /* Extra descriptors */int extralen;int enabled;//使能的话urb才能被提交到此端口};

 

你可能感兴趣的文章
excel进行矩阵计算
查看>>
基于Android平台的动态生成控件和动态改变控件位置的方法
查看>>
BOM
查看>>
iOS: Block的循环引用
查看>>
MySQL类型转换
查看>>
变量声明提升1
查看>>
系列文章目录
查看>>
手把手教你如何提高神经网络的性能
查看>>
前端布局原理涉及到的相关概念总结
查看>>
递归调用 VS 循环调用
查看>>
使用sstream读取字符串中的数字(c++)
查看>>
树莓派下实现ngrok自启动
查看>>
javascript静态类型检测工具—Flow
查看>>
MachineLearning-Sklearn——环境搭建
查看>>
node学习之路(二)—— Node.js 连接 MongoDB
查看>>
《深入理解java虚拟机》学习笔记系列——垃圾收集器&内存分配策略
查看>>
通过XAML Islands使Windows桌面应用程序现代化
查看>>
Javascript 深入浅出原型
查看>>
简单之极,搭建属于自己的Data Mining环境(Spark版本)
查看>>
Ruby 2.5.0概览
查看>>