打印

USB设备首次枚举第二次获取配置描述符后总复位【已更新】

[复制链接]
6434|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kokoromi|  楼主 | 2013-5-7 14:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kokoromi 于 2013-5-8 12:41 编辑

做了一个自定义HID设备,首次枚举后会提示硬件安装出现问题。
我的配置描述符集合是34字节,端点0最大包长为8字节
调试环境下发现,设备第二次获取配置描述符集合的时候,本应该触发5次IN中断,但是却触发了8次IN中断,然后就复位了...而且复位之后还能继续获取字符串描述符和报告描述符... 但是拔出USB然后再插入枚举就一切正常了,主机第二次获取配置描述符的时候也正常的触发了5次IN中断,这是怎么回事啊?我都要崩溃了,这问题怎么这么诡异?只要我更改了设备描述符里的VID和PID,枚举的时候就会发生上面的情况,拔出再插入就正常...

发送数据这块和描述符我都检查好几遍了,没问题的,真是不明白,主机要想触发设备的IN中断,必须是设备清除了端点NAK使能发送后主机才能发来IN令牌并让设备发送数据并触发IN中断,为什么会在第一次枚举的时候多触发了3次IN中断呢,实在是不明白了,有人遇到过这情况吗? 望各位指点啊~


下面是枚举涉及到的描述符:


//定义设备描述符
const BYTE DeviceDescriptor[18] =
{
  0x12,                                   //描述符长度(18字节)
  0x01,                                   //描述符类型(设备描述符)
  0x10, 0x01,                         //USB协议版本(1.1)
  0x00,                                   //设备使用的类代码
  0x00,                                   //设备使用的子类代码
  0x00,                                   //设备使用的协议代码
  0x08,                                   //端点0最大包长
  0xFF, 0x88,                         //厂商 ID                                 
  0xEE, 0x99,                         //产品 ID
  0x00, 0x01,                         //设备版本号(1.0)
  0x01,                                   //厂商字符串索引
  0x02,                                   //产品字符串索引
  0x03,                                   //设备序列号字符窜索引
  0x01                                    //设备拥有的配置数
};

//定义配置描述符集合
const BYTE ConfigurationDescriptorGroup[34] =
{
  //配置描述符
  0x09,                                   //描述符长度(9字节)
  0x02,                                   //描述符类型(配置描述符)
  0x22, 0x00,                         //描述符总长度(不固定)
  0x01,                                   //该配置支持的接口数
  0x01,                                   //该配置的值
  0x00,                                   //该配置的字符串索引
  0x80,                                   //总线供电,不支持远程唤醒
  0xFA,                                   //总线最大电流输出(500mA)
  
  //接口描述符
  0x09,                                   //描述符长度(9字节)
  0x04,                                   //描述符类型(接口描述符)
  0x00,                                   //该接口的编号
  0x00,                                   //该接口的备用编号
  0x01,                                   //该接口使用的端点数
  0x03,                                   //该接口使用的类(自定义 HID类)
  0x00,                                   //该接口使用的子类
  0x00,                                   //该接口使用的协议
  0x00,                                   //该接口的字符串索引
  
  //HID描述符
  0x09,                                   //描述符长度(9字节)
  0x21,                                   //描述符类型(HID描述符)
  0x11, 0x01,                         //HID协议版本(1.11)
  0x00,                                   //国家代码(无)
  0x01,                                   //下级描述符数量(1个)
  0x22,                                   //下级描述符类型(报告描述符)
  0x15, 0x00,                         //下级描述符长度(不固定)
  
  //端点描述符
  0x07,                                   //描述符长度(7字节)
  0x05,                                   //描述符类型(端点描述符)
  0x81,                                   //端点地址(输入端点 1)
  0x03,                                   //端点类型(中断传输端点)
  0x40, 0x00,                         //端点最大包长 64字节
  0x0A                                    //端点查询时间(10ms)
};

//定义字符串描述符
const BYTE StringDescriptorID0[4] =
{
  //语言 ID描述符(索引 0)
  0x04,                                   //描述符长度(4字节,不固定)
  0x03,                                   //描述符类型(字符串描述符)
  0x09, 0x04                          //语言 ID号(美式英语)
};
const BYTE StringDescriptorID1[10] =
{
  //厂商字符串描述符(索引 1)
  0x0A,                                   //描述符长度(10字节)
  0x03,                                   //描述符类型(字符串描述符)
  0x44, 0x00,                         //D
  0x46, 0x00,                         //F
  0x4D, 0x00,                         //M
  0x43, 0x00                          //C
};
const BYTE StringDescriptorID2[42] =
{
  //产品字符串描述符(索引 2)
  0x2A,                                   //描述符长度(42字节)
  0x03,                                   //描述符类型(字符串描述符)
  0x48, 0x00,                             //H
  0x41, 0x00,                             //A
  0x52, 0x00,                             //R
  0x54, 0x00,                             //T
  0x20, 0x00,                             //
  0x48, 0x00,                             //H
  0x61, 0x00,                             //a
  0x6E, 0x00,                             //n
  0x64, 0x00,                             //d
  0x68, 0x00,                             //h
  0x65, 0x00,                             //e
  0x6C, 0x00,                             //l
  0x64, 0x00,                             //d
  0x20, 0x00,                             //
  0x44, 0x00,                             //D
  0x65, 0x00,                             //e
  0x76, 0x00,                             //v
  0x69, 0x00,                             //i
  0x63, 0x00,                             //c
  0x65, 0x00                              //e
};
const BYTE StringDescriptorID3[18] =
{
  //设备序列号字符串描述符(索引 3)
  0x12,                                   //描述符长度(18字节)
  0x03,                                   //描述符类型(字符串描述符)
  0x32, 0x00,                             //2
  0x30, 0x00,                             //0
  0x31, 0x00,                             //1
  0x33, 0x00,                             //3
  0x30, 0x00,                             //0
  0x34, 0x00,                             //4
  0x32, 0x00,                             //2
  0x36, 0x00                              //6
};

//定义报告描述符(自定义 HID设备)
const BYTE ReportDescriptor[21] =
{
  0x05, 0x01,                             // USAGE_PAGE (Generic Desktop)
  0x09, 0x00,                             // USAGE (Undefined)
  0xa1, 0x01,                             // COLLECTION (Application)
  0x15, 0x00,                             //   LOGICAL_MINIMUM (0)
  0x25, 0x7f,                             //   LOGICAL_MAXIMUM (127)
  0x19, 0x01,                             //   USAGE_MINIMUM (1)
  0x29, 0x08,                             //   USAGE_MAXIMUM (8)
  0x75, 0x08,                             //   REPORT_SIZE (8)
  0x95, 0x01,                             //   REPORT_COUNT (1)
  0x81, 0x02,                             //   INPUT (Data,Var,Abs)
  0xc0                                    // END_COLLECTION
};

调试信息如下:
USB复位中断:USB复位
USB挂起中断:USB挂起
USB挂起中断:USB挂起
USB复位中断:USB复位
USB端点0 输出中断:获取设备描述符
USB端点0 输入中断
USB复位中断
USB端点0 输出中断:设置地址
USB端点0 输出中断:获取设备描述符
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输出中断:获取配置描述符
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输出中断:获取字符串描述符(语言ID)
USB端点0 输入中断
USB端点0 输出中断:获取字符串描述符(产品序列号)
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输出中断:获取配置描述符
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB复位中断
USB端点0 输出中断:获取字符串描述符(语言ID)
USB端点0 输入中断
USB端点0 输出中断:获取字符串描述符(产品字符串)
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
... ...

后面的就省略了,都是请求字符串描述符、设备描述符、配置描述符、设置配置、设置空闲和获取报告描述符等等。麻烦大家帮我看看我的 设备描述符 和 配置描述符 有没有问题,只要修改完设备描述符里的厂商ID和产品ID然后插入USB就会出现上面的调试信息里的情况,第二次获取配置描述符集合的时候多了三次输入中断并且紧接着就复位了,但是,只要不修改厂商ID和产品ID再插入USB,调试信息红色部分就没有了,一切正常。

麻烦大家帮我看看到底哪儿出的问题,太诡异了~ 不胜感激~~

相关帖子

沙发
kokoromi|  楼主 | 2013-5-8 12:38 | 只看该作者
本帖最后由 kokoromi 于 2013-5-9 08:30 编辑

麻烦大家帮我分析分析,实在是不知道错误出在哪儿。。。@computer00 圈圈 我这设备和配置描述符有问题吗,这个现象是什么原因啊~

使用特权

评论回复
板凳
computer00| | 2013-5-11 00:15 | 只看该作者
估计是对总线复位没处理好引起的。

使用特权

评论回复
地板
kokoromi|  楼主 | 2013-5-12 15:31 | 只看该作者
computer00 发表于 2013-5-11 00:15
估计是对总线复位没处理好引起的。

复位都没问题啊,要是有问题,为什么就一次不好使,而以后每次连接USB都没问题啊? 现在问题诡异就在这里:修改完VID和PID 连接USB就会出现上面的情况,但是拔出来在连接就没问题了...

使用特权

评论回复
5
STARM| | 2013-6-17 21:17 | 只看该作者
http://blogs.msdn.com/b/usbcoreblog/archive/2010/09/11/9915562.aspx

MS OS Descriptor Query

Once validated, the value in the descriptor’s bVendorCode field will be stored
in the registry on a per VID/PID/Revision basis,
under the USBFLAGS registry subkey in the “osvc” registry value.  

Subsequent enumerations of any device with the same VID/PID/Revision will
read the bVendorCode from this registry value rather than querying the device.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags\<VVVVPPPPRRRR>

osvc : 01 01

使用特权

评论回复
6
kokoromi|  楼主 | 2013-6-17 21:23 | 只看该作者
STARM 发表于 2013-6-17 21:17
http://blogs.msdn.com/b/usbcoreblog/archive/2010/09/11/9915562.aspx

MS OS Descriptor Query

谢谢你了,这个问题你在另一个帖子里已经回了,现在已经解决了 呵呵~

使用特权

评论回复
7
bluesky_kun| | 2013-6-28 17:00 | 只看该作者
哪个帖子?

使用特权

评论回复
8
kokoromi|  楼主 | 2013-6-28 21:28 | 只看该作者
bluesky_kun 发表于 2013-6-28 17:00
哪个帖子?

是枚举的时候主机发送了一个OS描述符,我没有响应所以复位了,添加OS描述符的响应代码就OK了  

https://bbs.21ic.com/icview-557770-1-2.html

使用特权

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

本版积分规则

111

主题

344

帖子

3

粉丝