1. USB OTG 基础概念:OTG 起源、角色定义、应用场景
做嵌入式这些年,调试过不少 USB 相关的坑。要说哪个最让人头疼,OTG 角色切换排前三。很多工程师觉得 OTG 就是手机能接 U 盘那么回事,真上手调才发现——插上设备没反应、角色切不过来、供电时序乱套……一查就是半天。所以这门课第一件事,咱们先把 OTG 的底子打牢。你只有搞懂它从哪来、怎么定义角色、实际用在哪些场景,后面调试异常时才不会抓瞎。
1.1 OTG 的起源——为什么需要它?
USB 1.0/1.1 时代,PC 永远是 Host(主机),外设永远是 Device(设备)。谁插谁、谁来供电、谁来发起通信,清清楚楚。但到了 2000 年左右,手机、相机、MP3 这些便携设备互相连的需求越来越多。你想想看,两台相机想互传照片,必须靠 PC 中转,多麻烦。
我记得 2003 年第一次接触 OTG 规范(USB On-The-Go,Supplement 1.0)。它的初衷很简单:让两个原本都是 Device 的设备能直接通信,并且能动态决定谁当 Host、谁当 Device。说白了,就是去掉 PC 这个中间人。
核心结论:OTG 不是新的 USB 总线,而是对 USB 2.0 协议的扩展。它在标准 USB 基础上新增了 角色协商(HNP) 和 供电切换(SRP) 两个机制。
1.2 角色定义——A-Device 与 B-Device
OTG 里不再叫 Host 和 Device,而是引入了一对新概念:A-Device 和 B-Device。我当年刚学时也被绕晕过,其实就一句话:谁提供电源,谁就是 A-Device。
| 概念 | 定义 | 默认角色 | 能否切换 |
|---|---|---|---|
| A-Device | OTG 会话中承担供电方(VBus 提供者) | Host(主机) | 可协商为 Peripheral |
| B-Device | OTG 会话中受电方(VBus 消费者) | Peripheral(外设) | 可协商为 Host |
实际插拔时,物理连接器上的 ID 引脚决定了谁是 A、谁是 B。Mini-A/Micro-A 插头将 ID 接地,Mini-B/Micro-B 插头使 ID 悬空。我曾经在项目里遇到过 ID 引脚虚焊,导致角色一直认错,查了两天才定位——嗯,硬件坑总是藏在最基础的地方。
个人习惯:原理图上我总会在 ID 引脚旁边标注“接地为 A-Device,悬空为 B-Device”,并拉一个 10kΩ 下拉电阻到地。这样即使插头未完全插入,默认状态也往 A 设备偏,避免上电时序卡死。
1.3 关键机制:HNP 与 SRP
OTG 的核心靠两个协议:
- SRP(Session Request Protocol):会话请求协议。B-Device 想发起通信时,必须先通过 SRP 唤醒 VBus,让 A-Device 感知到自己的存在。我见过不少板子 SRP 时序不对,B 设备拉低了数据线但 VBus 并没有抬起来,最后超时无响应。
- HNP(Host Negotiation Protocol):主机协商协议。一旦 VBus 稳定,双方可以通过数据线上的脉冲序列协商到底谁当 Host。这个过程中,A 设备要短暂释放总线控制权,B 设备接管。
你想想看,如果 HNP 时序里某个脉冲宽度超标,USB 控制器可能会认为对方不支持 HNP,直接退化为标准 USB 挂起模式——这时候角色切不过来,但系统还不报错,最难调。
1.4 应用场景——OTG 到底用在哪儿
按照经验,我把 OTG 应用分成三类:
- 设备互联类:手机连 U 盘、相机连打印机、游戏手柄连平板。这类场景最常见,也是我们调试最多的。我记得有个项目,手机接 U 盘后文件管理器一直转圈,最后发现是 U 盘里有个坏块导致枚举超时,OTG 层在 SRP 成功后一直没等到 Descriptor,设备端直接挂了。
- 数据采集类:工业现场仪表用 OTG 连接平板电脑做配置读取。这里经常遇到供电不足的问题——仪表自耗电大,平板给不了 500mA,SRP 请求发出去后 VBus 电压掉到 4.4V 以下,设备直接掉线。
- 充电+数据混合场景:部分平板支持 OTG 同时充电(充电时仍然是 A-Device)。这属于非标扩展,我踩过坑:某平台代码里把充电唤醒和 SRP 脉冲混在一起,结果一插外设就进入充电状态,角色切不动。
| 场景 | 典型设备对 | 主要异常点 |
|---|---|---|
| 设备互联 | Android 手机 ↔ U 盘 | 设备枚举超时、供电不足 |
| 数据采集 | 工业仪表 ↔ 平板 | SRP 握手失败、VBus 电压塌陷 |
| 充电+数据 | 平板 ↔ OTG Hub | 角色切换冲突、充电电流受限 |
1.5 给初学者的避坑指南
曾经我踩过的坑,希望你一个也别碰:
- ID 引脚不要省。 有人想用软件方法绕过 ID 检测,只靠 VBUS 判断角色。这在 OTG 规范里不合法,而且实际兼容性极差——遇到不同线缆长度、寄生电容差异,很可能一边认为自己是 A,另一边也认为自己是 A,两边都供电,最后烧端口。
- VBus 电容别偷懒。 标准要求 VBus 上至少 1μF,最好 10μF。容量太小,B 设备拉数据线请求 SRP 时,瞬间电流会导致 VBus 跌到欠压阈值以下,A 设备会误判成过流断开。
- RESET 时序别乱动。 HNP 协商完成后,新 Host 要对总线做复位(USB Reset)。如果复位脉冲宽度小于 10ms,有些老设备不会响应,角色切换后直接丢枚举。
嗯,记住这些,你就已经避开了 OTG 调试里 60% 的低级坑。剩下的 40%,咱们在后面 29 章里一个一个拆。别急,先把基础概念刻在脑子里。