打印

USB枚举时为什么要读3、4次设备描述符?

[复制链接]
7290|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wlsui|  楼主 | 2007-11-8 23:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问为什么USB枚举时要读3、4次设备描述符?
第一次读完后马上设置地址,然后第二次读取,再读9字节配置描述符,接着第三次读取,然后读取所有的配置描述符,有的甚至接着读第四次

我现在的问题是:

1、为什么PC机第一次读设备描述符时指定的数据长度是0x40,设备描述符不是固定为0x12字节吗?而之前我也好象在哪本书上看到说第一次读只读8个字节,请问到底是为什么?

2、为什么读取设备描述符之前要重新读取一次设备描述符?读到的值不是和第一次读取到的一样吗?

请高手指教!如果平常人能帮忙解答,那再幸福不过了
评论
lwei2 2020-9-2 09:12 回复TA
楼主,请问在win下如何获取插入的对应的USB设备描述符(并把标准的设备如鼠标,键盘排除在外)? 

相关帖子

沙发
平常人| | 2007-11-9 13:56 | 只看该作者

USB枚举时为什么不可以读3、4次设备描述符呢?

首先我要问一下LZ为什么要问这个问题?设备描述符是一个USB设备的最基本描述,是不会轻易改变的,PC多次读这个描述符,对于设备来说并没有任何的不妥,也符合USB协议的规定。

至于为什么USB枚举时要读3、4次设备描述符的问题,答案很简单,通常每一次读设备描述符的操作是从不同的设备驱动中发出来的,设备驱动互相调用时不会传递很多信息,新的驱动获得控制权后自然要读一下设备描述符以确认这是它能处理的设备。

举一个USB转232设备在Windows下的例子,一种可能的枚举过程是:
1)设备插入PC,OS识别出有新的USB设备插入,OS加载“识别USB设备的驱动”
2)“识别USB设备的驱动”读出新的USB设备的设备描述符,根据VID/PID找出相应的设备驱动
3)在这个例子中,“识别USB设备的驱动”会加载CDC驱动并把控制转给CDC驱动
4)CDC驱动读出设备描述符和其它描述符,发现需要装载USB-COM的Mini-Driver
5)CDC驱动又把控制转给这个Mini-Driver
6)Mini-Driver又要读一次设备描述符
7)Mini-Driver完成其它配置,并转入数据传输。

这个例子中涉及到3个驱动,所以至少会出现3次读设备描述符;如果某个驱动中不想开辟专用的存储空间存放设备描述符的信息,它还有可能多次读设备描述符。

所以USB Host多次读设备描述符并不奇怪,设备端必须支持这样的操作。

从设备端看,它应该在Host每次读设备描述符时返回相同的(常数)设备描述符,但有些特殊的应用除外。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
zifan + 1 很给力!
板凳
wlsui|  楼主 | 2007-11-9 22:55 | 只看该作者

茅塞顿开!

看到“每一次读设备描述符的操作是从不同的设备驱动中发出来的”时,感觉茅塞顿开了!

我今年六月底刚毕业,七月份开始参加工作,典型的菜鸟级人物。国庆前的时候公司让我做一个USB方面的项目,目标是OTG。由于之前也没有接触过USB方面的东西,所以花了半个多月学习了下DEVICE,然后从10月中旬开始做HOST,由于主机方面的资料比较少,而自己的时间也比较紧,所以也没法去看太多的各种资料,缺乏完备的知识体系。现在都是照着OHCI规范的说明做,有些东西都是看USB设备插入PC机时PC机会做一些什么样的操作,我就照着做,就像前面的读多次设备描述符一样,但至于为什么,则是有些理解有些就很迷惑了。

现在HOST方面已经可以实现BULK和Intrrupt传输了,实现了与之前公司做的DEVICE设备的数据传输。同步传输暂时还不打算做。下一步计划学习大容量存储类,加入文件系统,实现U盘的读取,争取月底完成HOST方面的工作,下月初开始尝试OTG方面的。
到时有什么问题还请您这个21IC上公认的USB最高手多多指点!

使用特权

评论回复
地板
icecut| | 2007-11-12 23:11 | 只看该作者

我回答第二个问题

由于好多驱动是通用驱动,例如我开发的ATMEL的USB,用DDK提供的代码枚举,这样通用驱动会出现一个问题:有些描述符大小不确定,这样就有2种解决方案,例如DS3.2默认1kb大小缓冲区,读取那个几十字节的描述符。是一种浪费,另一种比较好的方法是先读十几个字符,从中获得描述符大小,然后FREE刚才的内存,重新申请和描述符相同的缓冲区然后读入。所以就出现你不明白的第二个问题了

使用特权

评论回复
5
wlsui|  楼主 | 2007-11-13 21:09 | 只看该作者

我现在做法:

对设备描述符读两次,开始时默认EP0最大包大小为8字节,第一次只读8字节,而不是全部的18字节,因为发现有些设备EP0的最大包只有8字节,读8字节刚好能够读回设备的EP0最大包值,然后设置地址,接着以第一次确定的设备EP0最大包值读取全部的18字节描述符(可能要IN多次,视最大包值而定)

对配置描述符,第一次读完9字节后,已可以确定有多少字节的描述符,此时动态申请一个该大小的缓冲区,用完后释放.

使用特权

评论回复
6
平常人| | 2007-11-13 21:13 | 只看该作者

只看标题还以为5楼是巫师呢,哈哈

根据USB的标准协议,所有描述符都是静态的,是用来描述一个设备的各项特征,所以只要你愿意读多少次都没关系。

使用特权

评论回复
7
computer00| | 2007-11-13 21:30 | 只看该作者

通常驱动程序是这么干的:

设备刚接入时,只读一次设备描述符,可以申请读18字节,也可以申请更多的,但是只要检测到一个输入包,
就够了,而不管端点0多大,即使申请的长度未够,也切换到设置地址阶段.

设置地址后,再根据刚刚获取到的端点0大小来读取完整的设备描述符.

使用特权

评论回复
8
huangqi412| | 2007-11-14 18:19 | 只看该作者

学习了

使用特权

评论回复
9
wlsui|  楼主 | 2007-11-14 22:01 | 只看该作者

现在已经可以对SD卡进行读写操作了

花了一天的时间看了下Bulk Only和UFI规范,现在已经可以通过读卡器对卡进行读写操作了,不过还没有挂接文件系统,只是写一块数据到某一地址,然后将该块数据读出来校验.发现大容量类协议相对来说还是比较简单的.

使用特权

评论回复
10
fengyeu| | 2007-11-19 08:16 | 只看该作者

学习!

学习!

使用特权

评论回复
11
dragon_hn| | 2007-11-20 15:55 | 只看该作者

不同的WINDOWS版本不一样

不同的WINDOWS版本不一样,多试试就知道了,为了你的产品的兼容性

使用特权

评论回复
12
wlsui|  楼主 | 2007-11-21 22:01 | 只看该作者

这两天一直在测

这两天到处找各种各样的读卡器,U盘,MP3等大容量设备进行测试

使用特权

评论回复
13
Lyc1992| | 2013-8-26 23:49 | 只看该作者

使用特权

评论回复
14
zifan| | 2013-9-6 14:32 | 只看该作者
搬个凳子上课

使用特权

评论回复
15
东方赤那| | 2013-9-27 11:34 | 只看该作者
看了这个自然就明白了

使用特权

评论回复
16
wenunit| | 2020-10-10 15:34 | 只看该作者
好**。。。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

263

帖子

1

粉丝