USB枚举过程及AOA连接波形分析

2023-10-21 08:50

本文主要是介绍USB枚举过程及AOA连接波形分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文记录为了解决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连接正常的波形,先把波形图分为了几部分后面根据每个部分单独分析。

从USB线连接到AOA连接过程的波形图

阶段A:发现设备

A:该部分为HUB发现USB设备接入,D+数据线上设备端的3.3V上拉电阻拉高,此时HOST端的HUB检测到设备接入。稳定100ms后HOST发出reset信号。reset部分放在B阶段讨论。

阶段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信号。
usbmon log如下:
d9224620 可以看出该设备的vid=22d9,pid=2046(参见注意2)

e57d6400 889277761 S Co:1:001:0 s 23 01 0014 0001 0000 0
e57d6400 889277796 C Co:1:001:0 0 0
e57d6400 889338213 S Ci:1:000:0 s 80 06 0100 0000 0040 64 <
e57d6400 889338354 C Ci:1:000:0 0 18 = 12011002 00000040 d9224620 23020102 0301
e57d6400 889338416 S Co:1:001:0 s 23 03 0004 0001 0000 0
e57d6400 889338473 C Co:1:001:0 0 0
e57d6400 889397624 S Ci:1:001:0 s a3 00 0000 0001 0004 4 <

B5

阶段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

这篇关于USB枚举过程及AOA连接波形分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/253299

相关文章

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

MySQL中的交叉连接、自然连接和内连接查询详解

《MySQL中的交叉连接、自然连接和内连接查询详解》:本文主要介绍MySQL中的交叉连接、自然连接和内连接查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、引入二、交php叉连接(cross join)三、自然连接(naturalandroid join)四

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.