USB移动设备的定位
通常的USB设备可以分为五大类:显示器、通讯设备、音频设备、人机输入和海量存储。
而海量存储又包含了两大部分:传输方式和控制方式。
传输方式主要有:CBI传输和Bulk_only传输。
控制方式主要有:ATA命令和UFI命令规范。
CBI即指:Control / Bulk / Interrupt。因此,Bulk_only传输可以看成CBI中包含的一种传输方式。
对于USB移动设备,使用的是Bulk_only传输方式,即批量传输方式。同时,USB移动设备遵从UFI命令规范。
对于CBI传输和ATA命令块,主要用于对硬盘的管理。
在BusHound6.0观察PC连接的Device,可以看到比较细致的分类。
BusHound显示的除了一些似曾相识的设备外,还有两个主要的概念:Hub和Controller。
阅读任何一份和USB协议相关的文档,都能看到一个经典的金字塔图,告诉你Controller和USB设备的关系。用文字描述这个图大概是这样子的:“一个USBControl下只有一个RootHub,一个RootHub可以接多个Hub或USB设备,如果接的是Hub,则该Hub还可以接Hub和USB设备……”。
但是,并非连接的层数可以这样无止境下去,而设备个数也不是unlimited。USB协议做了这样的规定,以RootHub为起点,层数最多不能超过7层,也就是说任何一个USB系统中最多可以允许5个USB Hub级联。一个复合设备(CompoundDevice)将同时占据两层或更多层。设备(包括USB设备和Hub)不能超过127个。不能超过127个设备的原因是USB Controller只用了7Byte用于记录设备地址。
此外,需要注意的是,一个USB Controller下只有一个RootHub,所有需要连接到USB Controller的设备都是直接或间接的连接在该RootHub上。RootHub其实是一个特殊的USB Hub,它集成在USB Controller中,因此并不占用地址。即有限的127设备里面并不包含RootHub。
还有一个概念,没有在上图出现,但是却十分重要,那就是:EndPoint。
EndPoint,中文名:端点,常用缩写EP。
EndPoint一般后面会跟个序号,如EndPoint0、EndPoint1、EndPoint2……
一般情况下,我们常说的一个EndPoint的输入输出,其实指的的是一组EndPoint,因为单个EndPoint实际上只有输入或输出功能,即它是单方向的。
一组EndPoint之间的通讯(或者说数据传输),它们建立的“无形”通道,被称作管道(Pipe)。
在EndPoint0、EndPoint1、EndPoint2……中,以EndPoint0最为特殊,因为它被USB协议规定为缺省端点,即无论什么USB设备,无论该USB设备具备多少个EndPoint,EndPoint0总是必须的,它被用于控制命令的传输。在BusHound6.0里面,可以看到EndPoint0发送的命令除了数据传输,都是CTL。
EndPoint0之间的通道被称为缺省通道。
如上图,红圈里面的0表示当前的通讯是EndPoint0的通讯,发送CTL命令用于获取设备描述符。而红圈2表示当前通讯的是EndPoint2。
BusHound的使用操作很简单,无须过多介绍。但有几点注意:
1、如果需要观察更加全面的消息交互,需要选上USB移动存储设备的上一层。比如需要查看EndPoint0枚举过程。
2、前面说到USB移动存储使用的是UFI命令规范。UFI是个什么东西?
一般可以把UFI看成是SCSI命令的一个子集。
UFI包含三种字长的命令:6bit、10bit、12bit,在window下通常使用12bit。
UFI规范里包含的SCSI命令如下:
指令代码 |
指令名称 |
说明 |
04h |
Format Unit |
格式化存储单元 |
●12h |
Inquiry |
索取器件信息 |
1Bh |
Start / Stop |
Load / unload |
55h |
Mode select |
允许Host对外部设备设置参数 |
●5Ah |
Mode sense |
向Host传输参数 |
●1Eh |
Prevent / allow medium removal |
写保护 |
●28h |
Read(10) |
Host读存储介质中的二进制数据 |
A8h |
Read(12) |
同上,比较详细 |
●25h |
Read capacity |
要求设备返回当前容量 |
23h |
Read Format capacity |
查询当前容量及可用空间 |
03h |
Request sense |
请求设备向主机返回执行结果及状态数据 |
01h |
Rezero Unit |
返回零轨道 |
2Bh |
Seek(10) |
为设备分配到特定地址 |
1Dh |
Send diagnostic |
执行固件复位并执行诊断 |
●00h |
Test unit ready |
请求设备报告是否处于ready状态 |
●2Fh |
Verify |
在存储中验证数据 |
●2Ah |
Write(10) |
从主机向介质写二进制数据 |
AAh |
Write(12) |
同上,比较详细 |
2Eh |
Write and verify |
写二进制数据并验证 |
3、对于海量存储而言,上面标记了“●”的命令是必须响应。当然,海量存储包括了USB移动存储设备,因此USB移动存储设备也必须响应这些命令。
4、上面第3点说明,对于海量存储设备的命令,部分命令码被重复定义不会导致通讯出错,因为它们根本不会被系统调用。
5、其实,细心一点,回顾上图,会发现无论是USB Controller、RootHub还是USB设备,其地址都是递增的,即不会重复。一开始我认为一个PC可能有多个USB Controller,后来我大胆推测,一个PC(或者说一块主板),只有一个USB Controller。【注:当然,如果这个地址只是BusHound自己分配的,那么所有推测就都没意义了。】
再后来,上网查了下,真相大白。
在USB2.0出来之前,一个主板上只有一个USBController,即USB1.1的Controller。USB2.0出来之后,为了支持USB2.0,只支持USB1.1的主板上就多加了一个USB2.0的适配器,但是这个适配器和USB1.1Controller是独立工作,互不影响的。而在USB2.0后面设计的主板,就只有一个USB Controller了,你也可以说是USB2.0Controller,但是这个USB2.0 Controller是支持USB1.0和USB1.1的,即兼容了FS和LS。
再再后来,我又做了一个推测,对于主板上这个唯一的USB Controller,它早已把地址做了划分,先对每个子Controller划分地址,同时标明该Controller会被用于连接哪些设备。接着按序又为每个子Controller的RootHub分配接下来的地址,然后才是Hub和USB移动存储设备。当然,如何划分,是不是这样划分,还有指定每个子Controller的用途,对于不同的主板应该有各自不同的规定。于是,从这个推测中得到一个推测的结论,一个PC上能够让用户外接的USB设备不可能有127个。
6、从协议分析仪可以看到BusHound显示的Controller都是什么样的USB Controller类型。
Host controller interface (HCI) is a registerlevelinterfacewhich allows ahost controller forUSB orFireWireto communicate with theoperatingsystem of apersonal computer.
Open Host Controller Interface, orOHCI,is anopen standard.
Universal Host Controller Interface (UHCI)was created by Intel forUSB 1.0 (full and low speeds).
Enhanced Host ControllerInterface (EHCI)is a high speed controller standard which is publicly specified. The USB-IFinsisted on this for USB 2.0 instead of having a different standard forPCI-based USB interfaces, which would have increased complexity and thereforecosts. Intel hosted the EHCI conformance testing, which helped to preventdivergence from the standard.
7、USB协议规定,USB的延长线不能超过5M,因此在实际使用时,最好使用短且粗的USB延长线。
8. 解析数据:a3 00 00 00 01 00 04 00
a3:其它类型请求=设备到主机,00:指定命令=GET STATUS ,00 00:值为0 ,00 01:设备 ,00 04:长度4
查看通讯的数据,需要在设置界面里,把IN、OUT两个勾选上
9.用BusHound测量出数据传输速率
在设置界面可以勾选命令响应时间的显示
10.只要是usb端和host端的通讯数据,bushound都可以抓到。另外Data数据区的长度是可以设置的。