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

相关文章

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

Java 枚举的常用技巧汇总

《Java枚举的常用技巧汇总》在Java中,枚举类型是一种特殊的数据类型,允许定义一组固定的常量,默认情况下,toString方法返回枚举常量的名称,本文提供了一个完整的代码示例,展示了如何在Jav... 目录一、枚举的基本概念1. 什么是枚举?2. 基本枚举示例3. 枚举的优势二、枚举的高级用法1. 枚举

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

SpringBoot集成SOL链的详细过程

《SpringBoot集成SOL链的详细过程》Solanaj是一个用于与Solana区块链交互的Java库,它为Java开发者提供了一套功能丰富的API,使得在Java环境中可以轻松构建与Solana... 目录一、什么是solanaj?二、Pom依赖三、主要类3.1 RpcClient3.2 Public

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Rust中的Option枚举快速入门教程

《Rust中的Option枚举快速入门教程》Rust中的Option枚举用于表示可能不存在的值,提供了多种方法来处理这些值,避免了空指针异常,文章介绍了Option的定义、常见方法、使用场景以及注意事... 目录引言Option介绍Option的常见方法Option使用场景场景一:函数返回可能不存在的值场景

SpringBoot整合kaptcha验证码过程(复制粘贴即可用)

《SpringBoot整合kaptcha验证码过程(复制粘贴即可用)》本文介绍了如何在SpringBoot项目中整合Kaptcha验证码实现,通过配置和编写相应的Controller、工具类以及前端页... 目录SpringBoot整合kaptcha验证码程序目录参考有两种方式在springboot中使用k