概述
title: usb描述符简述
tags: linux
date: 2018/12/18/ 18:25:23
toc: true
---
usb描述符简述
转载自cnblog
具体描述符 https://blog.csdn.net/hushiganghu/article/details/54929066
在USB描述符中,从上到下分为四个层次:
- USB设备描述符(usb_device_descriptor)
- USB配置描述符(usb_config_descriptor)、
- USB接口描述符(usb_interface_descriptor)、
- USB端点描述符(usb_endpoint_descriptor)、
- USB接口描述符(usb_interface_descriptor)、
- USB配置描述符(usb_config_descriptor)、
一个设置描述符可以有多个配置描述符
一个配置描述符可以有多个接口描述符(比如声卡驱动,就有两个接口:录音接口和播放接口)
一个接口描述符可以有多个端点描述符,一个USB接口代表一个逻辑上的设备,比如声卡驱动,就有两个接口:录音接口和播放接口
一个端点只有一个方向,端点0可读可写
比如集成了键盘和鼠标的USB设备,里面就是两个interface,一个是键盘,另一个是鼠标。Interface之间通常是隔离的,互相不干扰。
每个Interface(接口)下面有一个或者多个Endpoint(端点),这也是逻辑概念,比如QQ要通信,可能开好几个端口,同样U盘要跟主机通信,要有控制信号和数据信号,这些都是不同的端点。端点是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特定的数据结构
};
配置描述符
struct usb_config_descriptor {
__u8
bLength;
//描述符的长度
__u8
bDescriptorType;
//描述符类型的编号
__le16 wTotalLength;
//配置 所返回的所有数据的大小
__u8
bNumInterfaces;
//配置 所支持的接口个数, 表示有多少个接口描述符
__u8
bConfigurationValue;
//Set_Configuration命令需要的参数值
__u8
iConfiguration;
//描述该配置的字符串的索引值
__u8
bmAttributes;
//供电模式的选择
__u8
bMaxPower;
//设备从总线提取的最大电流
} __attribute__ ((packed));
接口描述符
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;
};
端点描述符
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才能被提交到此端口
};
转载于:https://www.cnblogs.com/zongzi10010/p/10155316.html
最后
以上就是鲜艳蛋挞为你收集整理的usb描述符简述(二)usb描述符简述的全部内容,希望文章能够帮你解决usb描述符简述(二)usb描述符简述所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复