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 panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499