注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

南方企鹅电子技术工作室

诚信,电子产品设计,嵌入式linux,电动车控制器

 
 
 

日志

 
 

USB协议深入分析 设置USB地址  

2011-03-25 15:28:57|  分类: USB资料 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

USB协议深入分析 设置USB地址

 
前面已经解释主控器怎么样发送设备描述符下来,然后设备返回相应的设备描述符。下一步主控器的动作是做什么呢?由于在USB总线上的设备有很多,为了区分不同的设备通讯,就需要给每个设备分配一个地址,这跟网络中的IP地址是一样的,或者跟MAC地址也是一样的。因而,接着下来就是主控器分配地址给设备,USB的设备地址是从1开始到127。下面就是接收到主控器发下来的数据包:00 05 01 00 00 00 00 00 由USB_SETUP_PACKET定义具体地分析这个数据,就可以知道应做什么样的响应了。下面就来解释这个操作。先取得bmRequestType的类型,也就是第一个字节,它是00。从USB协议里查看,它的方向位是主控器发送给设备,由D6D5位就知道它是USB协议里定义的标准请求,由D4-D0位知道它是USB设备接收这个包数据。bRequest是05,从前面已经介绍的类型,就知道它是设置地址,如下:SET_ADDRESS             5所以这个包需要按设置地址的格式去解释后面的数据。 由于USB协议可以知道,USB的设备地址放在字段wValue里,因它的值是01 00,按小端格式解释就是0x0001了。其它相应的字段wIndex和wLength应都是0,如果是其它非0的数据,是没有定义的。 USB的串行引擎通过这个地址来判断是否接收总线上的数据,如果发送的地址跟它一致,就会接收主控器发过来的数据,当然从这个设备发送出去的数据也带有这个地址,因此就可以让主控器识别不同的USB设备数据了。
前面已经介绍设置USB的设备地址,接着下来是做什么呢?其实有了设备地址后,主控器还会再次发送获取上面已经读取的设备描述符下来,如下:

80 06 00 01 00 00 12 00 然后USB设备也再次回应它,但这次发送的长度是0x0012了,不再是第一次64个字节长度了。接着USB设备就返回下面的描述符给主控器,也就是第一次已经发送的设备描述符,如下:12 01 10 01 00 00 00 40 00 80 00 80 00 01 04 2C 4A 01 这样分配地址之后,再次获取设备描述符成功了,接着下来就是主控器获取配置描述符。下面就是收到的配置描述符数据:80 06 00 02 00 00 09 00 分析上面的数据如下:bmRequestType是80,表示方向USB设备发送给主控器,接收设备是USB设备。bRequest是06,表示这是获取描述符。GET_DESCRIPTOR         6wValue是00 02。低字节表示偏移地址00,高字节表示描述符的类型。如下:CONFIGURATION          2所以这里的返回的设备描述符是配置描述符。wIndex是00 00。wLength是09 00。它表示返回描述符的长度。这里是9个字节。接着下来,就是设备返回配置描述符给主控器,发送的数据如下:09 02 22 00 01 01 00 01 32 发送的数据是按下面的结构来定义,这也是在USB协议里定义的格式。如下:typedef struct _USB_CONFIGURATION_DESCRIPTOR { BYTE bLength; BYTE bDescriptorType; WORD wTotalLength; BYTE bNumInterfaces; BYTE bConfigurationValue; BYTE iConfiguration; BYTE bmAttributes; BYTE MaxPower;} USB_CONFIGURATION_DESCRIPTOR; bLength是配置的长度,也就是配置结构的整个长度。在这里9个字节。bDescriptorType是描述符的类型,这里配置描述符,所以设置为02。wTotalLength是所有配置设置的结构长度。包括配置描述符、接口描述符、HID或者其它描述符和端点描述符的长度。这里是22 00,也就是0x0022个字节。bNumInterfaces是接口个数,这里一个。bConfigurationValue是配置的个数,当设置配置时发送的值。这时设置为1个配置。iConfiguration是说明配置的字符的偏移值。这里是0。bmAttributes是配置特性,D7位保留。D6位是说明是否自供电。D5位是否支持远程唤醒。D4—D0是保留,设置为0。MaxPower是使用的功率,它采用电流来表示。每2mA为单位,比如它的值是50时就表示是100mA的电流消耗。通过这样说明,主控器就知道这个设备是什么样的设备,有多少功能。  USB协议深入分析 字符串描述符上一次说到把配置描述符返回给主控器那里了,现在接着下来,就会收到主控器发来字符串描述符。如果在设备描述符那里指定没有字符串描述的话,在这里是不会收到字符串描述符的。由于我在设备描述符里指定有字符串描述符的偏移地址,因此,就收到主控器发出请求字符串描述符。收到的数据如下:
80 06 00 03 00 00 FF 00
bmRequestType是80,表示方向USB设备发送给主控器,接收设备是USB设备。
bRequest是06,表示这是获取描述符。GET_DESCRIPTOR         6
wValue是00 03。低字节表示偏移地址00,高字节表示描述符的类型,如下:
STRING                   3
wIndex是00 00。
wLength是FF 00。它表示返回描述符的长度。这里是256个字节。
因此,这个获取字符串描述符,就是从字符串描述内存里,0偏移地址开始的位置读取第一个字符串描述符返回给主控器。接着就返回下面的数据给主控器:
04 03 09 04
上面的数据是按字符串描述符来组织的,它的结构,我定义结构如下:
typedef struct _USB_STRING_DESCRIPTOR {
 BYTE bLength;
 BYTE bDescriptorType;
 WORD bString/*[]*/;
} USB_STRING_DESCRIPTOR;
 
bLength是所有数据的长度。在这里是4。
bDescriptorType是描述类型,这里字符串描述符,所以它是3。
bString是可变的字符数组。不超过254个应都可以的,并且它是使用UNICODE编码的字符串。在这里是09 04,这是美国英语的标识,0x0409。如果想输入中文的标识,只要改为0x0804就可以了。
通过这个字符串描述符,主控器就知道字符串描述符是使用什么语言说明的了,这样就可以支持全世界的语言标识。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/nitghost/archive/2009/05/28/4221034.aspx

  评论这张
 
阅读(3060)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018