Linux那些事儿 之 戏说USB(17)接口是设备的接口(二)

原创 2007年09月27日 15:41:00
最近看了一些韩国的反转剧,什么是反转剧?就是影片儿演到一半时如果让你猜最后的结局,十有八九都会出乎你的预料。虽然每片只有短短20多分钟,但论故事情节,比咱们的帘子幽梦之类的梦了几十集还不知道做啥的精彩的多。
咱们在生活中是不会有这般戏剧性的反转和悬念的,有的只是吃饭的人生,上班的人生,睡觉的人生。思源湖边做了多少次的白日梦毕业时就被扔到了湖水里,然后我们从平淡走向平庸。
不过这里还是有点小悬念的,前面struct usb_interface里表示接口设置的struct usb_host_interface就被有意无意的飘过了,咱们在这里看看它的真面目,同样在include/linux/usb.h文件里定义。
69 /* host-side wrapper for one interface setting's parsed descriptors */
70 struct usb_host_interface {
71         struct usb_interface_descriptor desc;
72
73         /* array of desc.bNumEndpoint endpoints associated with this
74          * interface setting. these will be in no particular order.
75          */
76         struct usb_host_endpoint *endpoint;
77
78         char *string;           /* iInterface string, if present */
79         unsigned char *extra;   /* Extra descriptors */
80         int extralen;
81 };
71行,desc,接口的描述符。什么叫描述符?我们的生活就是一个不断的遇到人认识人的过程,有些人注定只是擦肩而过,有些人却深深的留在我们的内心里,比如USB的描述符。实际上,usb的描述符是一个带有预定义格式的数据结构,里面保存了usb设备的各种属性还有相关信息,姓甚名谁啊,哪儿生产的啊等等,我们可以通过向设备请求获得它们的内容来深刻的了解感知一个usb设备。主要有四种usb描述符,设备描述符,配置描述符,接口描述符和端点描述符,协议里规定一个usb设备是必须支持这四大描述符的,当然也有其它一些描述符来让设备可以显得个性些,但这四大描述符是一个都不能少的。
这些描述符放哪儿?当然是在设备里。就好像你要把身份证放自己身上以免在哪里心情舒畅的散步时被新时代最可爱的人警察叔叔查到一样,你不会直接放他们那儿吧,然后在他们亲切慈祥的向你招手时,告诉他们说不就在你那儿么,那样的话等待你又是个什么样的结果,我不知道,我想你也不会想知道。咱们的描述符就在设备里,等着主机去拿。具体在哪儿?usb设备里都会有一个叫EEPROM的东东,没错,就是放在它那儿,它就是用来存储设备本身信息的。如果你的脑海里还残存着一些大学里的美好时光的话,应该还会记得EEPROM就是电可擦写的可编程ROM,它与Flash虽说都是要电擦除的,但它可以按字节擦除,Flash只能一次擦除一个block,所以如果要改动比较少的数据的话,使用它还是比较合适的,但是世界上没有完美的东西,此物成本相对Flash比较高,所以一般来说usb设备里只拿它来存储一些本身特有的信息,要想存储数据,还是用Flash吧。
具体到接口描述符,它当然就是描述接口本身的信息的。一个接口可以有多个设置,使用不同的设置,描述接口的信息会有些不同,所以接口描述符并没有放在struct usb_interface结构里,而是放在表示接口设置的struct usb_host_interface结构里。定义在include/linux/usb/ch9.h文件里
294 /* USB_DT_INTERFACE: Interface descriptor */
295 struct usb_interface_descriptor {
296         __u8  bLength;
297         __u8 bDescriptorType;
298
299         __u8 bInterfaceNumber;
300         __u8 bAlternateSetting;
301         __u8 bNumEndpoints;
302         __u8 bInterfaceClass;
303         __u8 bInterfaceSubClass;
304         __u8 bInterfaceProtocol;
305         __u8 iInterface;
306 } __attribute__ ((packed));
又看到了__attribute__,不过这里改头换面成了__attribute__,意思就是告诉编译器,这个结构的元素都是1字节对齐的,不要再添加填充位了。因为这个结构和spec里的Table 9.12是完全一致的,包括字段的长度,如果不给编译器这么个暗示,编译器就会依据你平台的类型在结构的每个元素之间添加一定的填充位,如果你拿这个添加了填充位的结构去向设备请求描述符,你想想会是什么结果。
296行,bLength,描述符的字节长度。协议里规定,每个描述符必须以一个字节打头来表明描述符的长度。那可以扳着指头数一下,接口描述符的bLength应该是9,两个巴掌就数完了,没错,ch9.h文件里紧挨着接口描述符的定义就定义了这个长度
308 #define USB_DT_INTERFACE_SIZE           9
297行,bDescriptorType,描述符的类型。各种描述符的类型都在ch9.h文件里有定义,对应spec Table 9.5。对于接口描述符来说,值为USB_DT_INTERFACE,也就是0x04。

299行,bInterfaceNumber,接口号。每个配置可以包含多个接口,这个值就是它们的索引值。

300行,bAlternateSetting,接口使用的是哪个可选设置。协议里规定,接口默认使用的设置总为0号设置。

301行,bNumEndpoints,接口拥有的端点数量。这里并不包括端点0,端点0是所有的设备都必须提供的,所以这里就没必要多此一举的包括它了。

302行,bInterfaceClass303bInterfaceSubClass304bInterfaceProtocol。这个世界上有许许多多的usb设备,它们各有各的特点,为了区分它们,usb规范,或者说usb协议,把usb设备分成了很多类,然而每个类又分成子类,这很好理解,我们一个大学也是如此,先是分成很多个学院,然后每个学院又被分为很多个系,然后可能每个系下边又分了各个专业,usb协议也是这样干的,首先每个DeviceInterface属于一个Class,然后Class下面又分了SubClass,完了SubClass下面又按各种设备所遵循的不同的通信协议继续细分。usb协议里边为每一种Class,每一种SubClass,每一种Protocol定义一个数值,比如mass storage Class就是0x08hubClass就是0x09

305行,iInterface,接口对应的字符串描述符的索引值。疑?这里怎么又跳出来一个叫字符串描述符的东东?你没看错我也没说错,除了前面提到的四大描述符,是还有字符串描述符,不过那四大描述符是每个设备必须支持的,这个字符串描述符却是可有可无的,有了你欢喜我也欢喜,没有也不是什么问题。使用lsusb命令看一下

localhost:/usr/src/linux/drivers/usb/core # lsusb
Bus 001 Device 013: ID 04b4:1081 Cypress Semiconductor Corp.
Bus 001 Device 001: ID 0000:0000

第一行里显示的是我手边儿的Cypress USB开发板,看里面的Cypress Semiconductor Corp.,这么一长串的东东从哪里来?是不是应该从设备里来?设备的那几个标准描述符,整个描述符的大小也不一定放得下这么一长串,所以,一些设备专门准备了一些字符串描述符(string descriptor),就用来记这些长串的东西。字符串描述符主要就是提供一些设备接口相关的描述性信息,比如厂商的名字,产品序列号等等。字符串描述符当然可以有多个,这里的索引值就是用来区分它们的。

说过了接口描述符,回到struct usb_host_interface76行,endpoint,一个数组,表示这个设置所使用到端点。至于端点的结构struct usb_host_endpoint,天这么热,让它先一边儿凉快凉快吧,不怕春光乍泄的话,可以去思源湖冲个凉,咱们先看完struct usb_host_interface再去说它。

78行,string,用来保存从设备里取出来的字符串描述符信息的,既然字符串描述符可有可无,那这里的指针也有可能为空了。

79行,extra80extralen,关于额外的描述符。除了前面提到的四大描述符还有字符串描述符外,还有为一组设备也就是一类设备定义的描述符,和厂商为设备特别定义的描述符,extra指的就是它们,extralen表示它们的长度。比如上海规定了,社保必须得交多少多少,公积金多少多少,有个最低的比例,有地儿觉得太少,给你多交些,叫补充什么金的,还有些地儿,觉得补充都不过瘾,像公务员这种特殊行业特别劳心劳力的,再加些特殊行业补贴等什么的,既规定了必须实现的,也给你特殊行业发挥的空间,当然怎么发挥就不是咱说了算了,不操那份儿心了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Linux那些事儿 之 戏说USB(13)接口是设备的接口(二)

前面struct usb_interface里表示接口设置的struct usb_host_interface就被有意无意的飘过了,咱们在这里看看它的真面目,同样在include/linux/usb....
  • zhqh100
  • zhqh100
  • 2015年03月24日 17:03
  • 710

Linux那些事儿 之 戏说USB(12)接口是设备的接口(一)

前面的前面已经说了,接口是设备的接口。设备可以有多个接口,每个接口代表一个功能,每个接口对应着一个驱动。Linux设备模型的device落实在USB子系统,成了两个结构,一个是struct usb_d...
  • zhqh100
  • zhqh100
  • 2015年03月24日 16:28
  • 704

Linux USB子系统(2) 设备、配置、接口、端点

linux usb子系统 设备 配置 接口 设置 端点
  • mingtianyueni
  • mingtianyueni
  • 2016年12月04日 22:35
  • 666

Linux那些事儿 之 戏说USB(34)接口的驱动

从上节的上节我们已经知道,usb_generic_driver在自己的生命线里,以一己之力将设备的各个接口送给了linux的设备模型,让usb总线的match函数,也就是usb_device_matc...
  • zhqh100
  • zhqh100
  • 2015年03月28日 21:06
  • 441

Linux那些事儿 之 戏说USB(17)向左走,向右走

drivers/usb/core/driver.c static int usb_device_match(struct device *dev, struct device_driver *drv...
  • zhqh100
  • zhqh100
  • 2015年03月25日 11:38
  • 505

USB的描述符及各种描述符之…

原文地址:USB的描述符及各种描述符之间的依赖关系(转自电脑圈圈)作者:狼之行    USB的描述符及各种描述符之间的依赖关系.USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,例如US...
  • Sun19910114
  • Sun19910114
  • 2014年08月19日 16:29
  • 1054

在ARM linux上使用usb接口的触屏

应公司需要,在现有设备上面要使用触摸屏,显示器的尺寸是15寸,于是自己从淘宝上面买了个15寸4线电阻屏回来,带Windows下的驱动,售后告诉我不支持Linux。在pc上面使用很不错。接下来的任务是用...
  • aifei7320
  • aifei7320
  • 2015年04月25日 12:54
  • 1874

Linux那些事儿 之 戏说USB(15)设备

struct usb_device结构冗长而又杂乱 include/linux/usb.h struct usb_device { int devnum; char devpath[16];...
  • zhqh100
  • zhqh100
  • 2015年03月25日 09:31
  • 983

Linux那些事儿 之 戏说USB(18)设备的生命线(一)

首先当然是你将usb设备连接在hub的某个端口上,hub检测到有设备连接了进来,它也知道有朋自远方来不亦乐乎,于是精神头儿就上来了,就觉得有必要为设备做点什么。它会为设备分配一个struct usb_...
  • zhqh100
  • zhqh100
  • 2015年03月25日 13:56
  • 677

USB 接口关联描述符

USB 接口关联描述符 (IAD) 允许设备将属于一个函数的接口组合在一起。本主题描述客户端驱动程序如何能够确定设备是否包含某个函数的 IAD。 通用串行总线规范版本 2.0 不支持将复合设备的多个...
  • litao_wang
  • litao_wang
  • 2014年01月06日 09:13
  • 1364
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux那些事儿 之 戏说USB(17)接口是设备的接口(二)
举报原因:
原因补充:

(最多只允许输入30个字)