本文记录为了解决某个手机在特殊条件下无法和车机连接问题(AOA协议连接),学习USB协议及驱动工作原理过程中整理的笔记。
方法: 阅读Universal Serial Bus Specification Revision 2.0,理解USB设备的识别及通信过程,理解高速通信握手过程,分析USB总线上的数据包。
工具: 示波器,usbmon
参考文档: Universal Serial Bus Specification Revision 2.0,Linux USB驱动源码
主机:USB HOST
设备:USB DEVICE
HUB:介于主机与设备之间的通信设备,位于主机端
文章目录
- 波形一览
-
- 阶段A:发现设备
- 阶段B:枚举设备
- 阶段C:分配地址与配置
- 阶段D:发现设备(2)
- 阶段E:枚举设备(2)
- 阶段F:分配地址与配置(2)
- 注意
-
- 1:为什么设备连接过程中出现了两次High-Speed握手配对?
- 2:usbmon log数据分析错误?
波形一览
截一个AOA连接正常的波形,先把波形图分为了几部分后面根据每个部分单独分析。
阶段A:发现设备
A:该部分为HUB发现USB设备接入,D+数据线上设备端的3.3V上拉电阻拉高,此时HOST端的HUB检测到设备接入。稳定100ms后HOST发出reset信号。reset部分放在B阶段讨论。
阶段B:枚举设备
首先将B处波形放大图贴出来:
B1:此处就是前面提到的HOST触发的reset信号,Specification中要求该信号不小于2.5us,设备端检测到信号后需要做出答复。
B2:此处的信号有device触发,为chirp K信号,device向D+上驱动电流,呈现出800mv的电压信号。Specification中要求持续时间1ms<t<7ms。
B3:此处为3对chirp K/J信号,由HOST触发,device检测到3对chirp KJ信号后需要切换至高速通信模式(断开上拉电阻,连接D+/D-上的高速终端电阻)
B4:此处为device做出高速模式切换后的信号,由于device的动作,D+ D-上的阻值由于并联减半,信号幅值降到400mv。经过若干个chirp KJ信号,高速通信握手完成,可以以高速模式进行通信。
B5:此部分就是USB枚举阶段开始,使用default addr获取USB设备描述符,获取之后触发reset信号。
由d9224620可以看出该设备的vid=22d9,pid=2046(参见注意2)
usbmon log如下:
e57d6400 889338354 C Ci:1:000:0 0 18 = 12011002 00000040 d9224620 23020102 0301
阶段C:分配地址与配置
由于在B5阶段HOST获取了Device的设备描述符之后,发出了reset信号,所以阶段C重新进行了一次高速通信握手(参见注意1),握手成功后再次获取USB设备描述符,然后给设备分配地址,之后使用新的地址进行配置属性,等等信息进行一系列交互。
如果要进行AOA设备切换,此处就有AOA设备切换指令51,51,53指令。
此处附上usbmon log进行分析
e524a900 889491606 S Ci:1:002:0 s c0 33 0000 0000 0002 2 < //51指令 51=0x33
e9870600 889491617 S Ci:1:002:0 s 80 06 0304 0409 00fe 254 <
e524a900 889491675 C Ci:1:002:0 0 2 = 0200
e9870600 889491707 C Ci:1:002:0 0 10 = 0a036d00 69006400 6900
e9870600 889491832 S Ci:1:002:0 s 80 06 0300 0000 00fe 254 <
e9870600 889491886 C Ci:1:002:0 0 4 = 04030904
e9870600 889491932 S Ci:1:002:0 s 80 06 0305 0409 00fe 254 <
e9870600 889492070 C Ci:1:002:0 0 28 = 1c034d00 49004400 49002000 66007500 6e006300 74006900 6f006e00
e524a900 889499253 S Co:1:002:0 s 40 34 0000 0000 0006 6 = 70617465 6f00 //52指令 52=0x34
e524a900 889499377 C Co:1:002:0 0 6 >
e524a900 889512760 S Co:1:002:0 s 40 34 0000 0001 0009 9 = 51696e67 4c696e6b 00 //52指令 52=0x34
e524a900 889512853 C Co:1:002:0 0 9 >
e524a900 889523353 S Co:1:002:0 s 40 34 0000 0002 0013 19 = e8bda6e8 be86e8bf 9ee68ea5 e8afb7e6 b18200 //52指令 52=0x34
e524a900 889523439 C Co:1:002:0 0 19 >
e524a900 889533907 S Co:1:002:0 s 40 34 0000 0003 0004 4 = 312e3000 //52指令 52=0x34
e524a900 889534009 C Co:1:002:0 0 4 >
e524a900 889544324 S Co:1:002:0 s 40 34 0000 0004 0037 55 = 68747470 733a2f2f 6466776c 6171722e 70617465 6f2e636f 6d2e636e 2f736a63 //52指令 52=0x34
e524a900 889544445 C Co:1:002:0 0 55 >
e524a900 889554918 S Co:1:002:0 s 40 34 0000 0005 0009 9 = 31323334 35363738 00 //52指令 52=0x34
e524a900 889555006 C Co:1:002:0 0 9 >
e524a900 889565111 S Co:1:002:0 s 40 35 0000 0000 0000 0 //53指令,53指令就是通知设备可以进行配件模式切换了
e524a900 889565190 C Co:1:002:0 0 0
d9812100 889598129 C Ii:1:001:1 0:2048 1 = 02
d9812100 889598161 S Ii:1:001:1 -115:2048 4 <
Device在接收到53指令后,会断开自己的UBS连接,之后进行重新连接,重新连接后的设备描述符就发生了变化(18D1)
阶段D:发现设备(2)
device接收到了53指令后,自己断开了USB设备后重新连接,因此阶段D只是重复了阶段A的工作
阶段E:枚举设备(2)
阶段E重复了阶段B的工作,唯一不同的此时HOST检测到的device虽然在物理上没有变化,实际上device的属性与阶段B完全不同,设备描述符也是不一致的。附上此处的usbmon日志,其中d118002d–表明着这是一个vid=0x18d1,pid=0x2d00的设备
e524a900 890157575 S Ci:1:003:0 s 80 06 0100 0000 0012 18 <
e524a900 890157799 C Ci:1:003:0 0 18 = 12011002 00000040 d118002d 23020102 0301
此处的PID与VID与阶段B的时候发生了变化,说明手机的配件模式切换成功啦~
阶段F:分配地址与配置(2)
阶段F重复了阶段C的工作,后续就保持正常的连接通信啦!!!至此手机与车机连接成功!
注意
在学习过程中遇到了两个问题
1:为什么设备连接过程中出现了两次High-Speed握手配对?
在“Universal Serial Bus Specification Revision 2.0”中找到了关键信息:
在reset之后,device撤销了之前在高速握手阶段对电阻的动作,此时恢复到了full-speed模式
If the device is being reset from a non-suspended high-speed state, then the device must wait no less
than 3.0 ms and no more than 3.125 ms (TWTREV) before reverting to full-speed. Reversion to fullspeed is accomplished by removing the high-speed termination and reconnecting the D+ pull-up
resistor. The device samples the bus state, and checks for SE0 (reset as opposed to suspend), no less
than 100 µs and no more than 875 µs (TWTRSTHS) after starting reversion to full-speed. If SE0 (reset) is
detected, then the device begins a high-speed detection handshake.(P154)
2:usbmon log数据分析错误?
usbmon log打出来的16位数据(word)是以小端模式根据内存地址由低到高进行打印的,与Specification中的数据对应关系如下:word数据的低8位在前面,高8位在后面
例:
usbmon log:
e4ab4000 32898545 S Ci:1:001:0 s a3 00 0000 0001 0004 4 < //Host向Hub请求当前的port口状态
e4ab4000 32898596 C Ci:1:001:0 0 4 = 0305 1000 //Hub向Host反馈当前port口状态
串口log:
03-11 12:08:27.453 0 0 E hub 1-0 : 1.0: hub_port_status (status = 0503)(change = 0010)
以word:0305 为例,此处的数据应该转换为0x0503与Specification中Table 11-21. Port Status Field, wPortStatus对应。
开始一直以0x0305去分析,怎么分析都是错误的,只好在驱动里加个log看一下,发现 usbmon中的数据包是小端模式储存 的需要注意!!!
to be continued