USB学习笔记一之描述符

  1. 逻辑层次及描述符

逻辑上,usb包含设备(Device),配置(Configuration),接口(Interface)和端点(Endpoint)四个层次。设备通常有一个或多个配置,配置通常有一个或多个接口,接口有零个或多个端点(端点0应该是没有算进去)。有多个配置的设备,任意时刻只能有一个配置处于激活状态。在这四个层次之外,还有一个设置(setting),它与接口相关,一个接口可以有多个设置(setting)。有多个设置(setting)的接口,任意时刻也只能有一个设置(setting)生效。

这四个层次都有相应的描述符(另外一个常用的描述符是字符串描述符),它们都可以通过GET_DESCRIPTOR命令获取。GET_DESCRIPTOR命令需要指定描述符类型,描述符索引等参数。需要注意的是,只能指定设备,配置和字符串三种描述符类型,而不能指定接口和端点这两种描述符类型。这是因为在获取配置描述符时,会把它包含的所有接口和端点描述符一次性获取过来。因此,获取配置描述符时,得到的内容将是:配置描述符,接口0的描述符,接口0的端点描述符,接口1的描述符,接口1的端点描述符,直至接口n。另外,GET_DESCRIPTOR命令的描述符索引参数,只对配置描述符和字符串描述符有效,分别用于获取指定的配置描述符和字符串描述符,而对设备描述符无效(原因应该是一个设备只有一个设备描述符)。

获取设备描述符后,可以知道此设备支持几个配置。获取配置描述符后,可以得到此配置的编号(bConfigurationValue,应该不是从0开始编号),还可以知道此配置支持几个接口。解析接口描述符后,可以得到此接口的编号(bInterfaceNumber,从0开始编号,直至接口数目减1),还可以知道此接口支持几个端点。注意,接口描述符里,并没有说明此接口支持几个设置(setting)。获取配置描述符时,会一并获取它支持的接口描述符,如果获取到相同编号(bInterfaceNumber)的多个接口描述符,则是同一个接口的不同设置(setting),这些接口描述符的设置(setting)编号(bAlternateSetting,从0开始编号,直至设置(setting)数目减1)应该不同。

  1. 描述符详情

2.1 设备描述符

struct usb_device_descriptor {
    __u8  bLength;            // 18
    __u8  bDescriptorType;    // USB_DT_DEVICE,0x01
    __le16 bcdUSB;            // usb spec版本号,对应 sysfs 中的 version
    __u8  bDeviceClass;       // 见第3节,“类别(Class)和协议(Protocol)”
    __u8  bDeviceSubClass;
    __u8  bDeviceProtocol;
    __u8  bMaxPacketSize0;    // 端点0一次可以处理的最大字节数
    __le16 idVendor;          // 厂商id
    __le16 idProduct;         // 产品id
    __le16 bcdDevice;         // 设备版本号
    __u8  iManufacturer;      // 厂商对应的字符串描述符的索引值
    __u8  iProduct;           // 产品对应的字符串描述符的索引值
    __u8  iSerialNumber;      // 序列号对应的字符串描述符的索引值
    __u8  bNumConfigurations; // 当前速度模式下的配置数目(不是设备支持的所有配置数目)。
} __attribute__ ((packed));

2.2 配置描述符

struct usb_config_descriptor {
    __u8  bLength;             // 9
    __u8  bDescriptorType;     // USB_DT_CONFIG, 0x02

    __le16 wTotalLength;       // GET_DESCRIPTOR 标准请求返回的总长度
    __u8  bNumInterfaces;      // 此配置包含的接口数目
    __u8  bConfigurationValue; // 可以看做是此配置的编号
    __u8  iConfiguration;      // 此配置对应的字符串描述符的索引值
    __u8  bmAttributes;        // 此配置的特征。bit7必须为1,bit6:self powered. bit5:can wakeup. bit4:battery powered.
    __u8  bMaxPower;           // 表示此设备需要的最大电流,以2mA为单位
} __attribute__ ((packed));

在内核usb代码中,struct usb_device结构体的config成员表示设备支持的所有配置,actconfig成员表示当前激活的配置。在sysfs中,configuration(若不为空)就是当前激活的配置的名称(对应配置描述符中的iConfiguration)。而sysfs中的bConfigurationValue与配置描述符中的bConfigurationValue对应,读回就是当前激活的配置的编号,写入就是激活指定编号的配置。

2.3 接口描述符

struct usb_interface_descriptor {
    __u8  bLength;            // 9
    __u8  bDescriptorType;    // USB_DT_INTERFACE, 0x04
    __u8  bInterfaceNumber;   // 接口编号(zero-base)
    __u8  bAlternateSetting;  // 设置(setting)编号(zero-base)
    __u8  bNumEndpoints;      // 包含的端点数目(端点0不包含在内)
    __u8  bInterfaceClass;    // 见第3节,“类别(Class)和协议(Protocol)”
    __u8  bInterfaceSubClass;
    __u8  bInterfaceProtocol;
    __u8  iInterface;         // 此接口对应的字符串描述符的索引值
} __attribute__ ((packed));

有一种可能,配置中包含的接口的数目为1,但有多个接口描述符,应该就是一个接口的不同设置(setting),因此有相同的接口编号(bInterfaceNumber),不同的设置(setting)(bAlternateSetting)编号。

2.4 端点描述符

struct usb_endpoint_descriptor {
    __u8  bLength;          // 7,9
    __u8  bDescriptorType;  // USB_DT_ENDPOINT, 0x05
    __u8  bEndpointAddress; // bit0~3表示端点编号,bit8表示端点方向
    __u8  bmAttributes;     // 端点属性
    __le16 wMaxPacketSize;  // 端点一次可以处理的最大字节数
    __u8  bInterval;        // 轮询时间间隔
    __u8  bRefresh;         // 音频相关
    __u8  bSynchAddress;    // 音频相关
} __attribute__ ((packed));
  1. 类别(Class)和协议(Protocol)

类别(Class)是针对设备和接口定义的,有一些类别(Class)仅针对设备,有一些类别(Class)仅针对接口,还有一些类别(Class)对设备和接口都有效。如下图所示:


class.jpg

而子类别(SubClass)和协议(Protocol)就根据类别(Class)的不同而不同了。
以常见的HID为例,它对应的子类别(SubClass)和协议(Protocol)如下图所示:


hid.jpg

而Mass Storage对应的则是:
mass.jpg

上述信息参考如下网址:
https://www.usb.org/defined-class-codes
https://www.usb.org/sites/default/files/hid1_11.pdf
https://www.usb.org/sites/default/files/Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf
更多信息,可以在下面的网址中搜索相关文档:
https://www.usb.org/documents?search=spec&items_per_page=50

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容

  • https://blog.csdn.net/songze_lee/article/details/77658094...
    郑行_aover阅读 3,532评论 0 0
  • Linux usb system(descriptor) 为了更好地描述USB设备的特征,USB提出了设备架构的概...
    Creator_Ly阅读 1,263评论 0 4
  • 1-USB 基本知识 USB的重要关键概念:1、 端点:位于USB设备或主机上的一个数据缓冲区,用来存放和发送US...
    xuefeng_apple阅读 540评论 0 2
  • USB是主从模式,设备和设备,主机与主机之间不能连接,为了解决这个问题出现了USB OTG,同一设备在不同场合可以...
    飞向深空阅读 193评论 0 0
  • USB是通用串行总线(Universal Serial Bus)的缩写。在USB1.0和USB1.1版本中,只支持...
    WilliamChou阅读 22,159评论 0 14