USB OTG 与双角色设备:ID 引脚、会话请求协议与主机/设备切换
更新时间:2026-09-19。前置:USB 端点与枚举、USB PHY 接口、USB Type-C 与 PD。普通 USB 是固定主从:PC 当 host 供电并枚举,U 盘当 device。OTG(On-The-Go)让一个口既能当主机又能当设备。
本文要回答的问题
- 一个口怎么知道这次该当主机还是设备?
- ID 引脚、A/B 插头如何决定角色和 VBUS 责任?
- SRP 和 HNP 分别解决什么问题,为什么需要 HNP?
- OTG 角色切换和 Type-C DRP 怎么对应?
一、双角色的硬件基础:ID 引脚
Micro-AB(OTG) receptacle 比普通口多一个 ID 引脚:
- 插入 A 插头时,插头把 ID 接地 → 该设备成为 A-device:默认主机,并负责在会话期间提供 VBUS。
- 插入 B 插头时,ID 悬空(上拉为高)→ 成为 B-device:默认设备(peripheral),不供电。
- 双角色设备控制器(DRD, Dual-Role Device)内部同时有主机控制器(如 EHCI 风格)和设备控制器,软件根据 ID 电平或运行时命令切换工作模式、复用同一 PHY(UTMI+/ULPI,见 USB PHY)。
ID 是传统 Micro/Mini-OTG 的判定方式;在 Type-C 上没有这个 ID 脚,角色由 CC 上的 Rp/Rd 与 DRP 决定(见 Type-C/PD),但「双角色、供电责任跟随数据源角色」的概念一致。
二、OTG 增强:SRP 与 HNP
OTG 不只是静态的「看 ID 定角色」,还定义了两个省电/灵活的协议:
SRP(Session Request Protocol,会话请求协议)
电池设备不想一直供 VBUS(费电)。当 B-device(设备)想开始一次通信而总线没电时,它可发起 SRP:通过数据线上的脉冲和/或 VBUS 脉冲,请求 A-device 打开 VBUS、开启会话。A-device 检测到后供上电、开始枚举。这样 A-device 平时可关 VBUS 省电,只在对端请求时才供电。
B-device 想通信,总线无电
→ 数据线脉冲(device 用上拉/PHY 产生) + 可选 VBUS 脉冲
A-device 检测到 SRP → 打开 VBUS → 复位/枚举 → 会话开始HNP(Host Negotiation Protocol,主机协商协议)
角色不必一直接 ID 固定。HNP 允许在同一根线、不重新插拔的情况下 A/B 设备交换主机角色:典型场景是手机(A-device,主机)连着 OTG 打印机,之后打印机需要临时接管主机职能。流程要点:
1. A-device(当前主机)通过 Set Feature 使能 B-device 的 HNP 支持,并挂起总线(suspend)
2. B-device 检测到挂起且被授权,可拉高(切断其 D+ 上拉/改驱动)请求成为主机
3. A-device 放弃主机、变成设备并接上自己的上拉
4. B-device 接管,复位总线、枚举原来的 A-device
5. 会话结束可再经 suspend 换回;A-device 始终负责 VBUS(供电责任不因 HNP 改变)HNP 的关键:数据角色可换,但 A-device 始终是默认的 VBUS 提供者;切换通过总线挂起和上拉/下拉的改变完成,软件/PHY 状态机要严格按超时执行。
三、VBUS 供电与放电责任
- A-device 必须能在需要时输出 VBUS(有限电流,OTG 常 8~500mA 级),并在会话结束、超时或故障时关闭。
- 角色切换/拔插后,VBUS 上大电容需要放电到安全电压才能开始下一次会话(OTG 规定放电时间/阈值),否则插入时可能被误判或损坏。
- B-device 绝不能长期供 VBUS(除 SRP 短脉冲外)。
- Type-C/PD 时代供电能力和角色由 CC/PD 协商,DRP 设备可做 power/ data 角色的独立交换(try.SNK/try.SRC 等),比老式 ID+SRP 更细。
四、典型运行流程(DRD 控制器 + 软件)
检测插入:
Micro-OTG: 读 ID → A=host / B=device
Type-C : CC DRP 解析 Rp/Rd → source/sink + host/device
初始化对应控制器:
host 模式: 开 VBUS → 复位(SE0) → 枚举 device(见 USB 枚举)
device 模式: 接上 D+/D- 上拉(FS/HS 选择) → 等主机复位枚举
运行中角色交换: HNP(OTG) 或 Type-C role swap
拔出/会话结束: 关 VBUS → 放电 → 回空闲软件通常要同时维护 host stack 和 gadget/device stack,并处理 PHY 复用、共用端点/FIFO 的重新配置(见 USB 端点)。
五、常见的坑
- ID 电平/上拉配置错:DRD 口 ID 未正确读取或默认状态错,角色判反。
- Type-C 上找 ID 脚:Type-C 无 ID,角色靠 CC DRP,混用模型导致不切换。
- VBUS 供电责任错:B-device 长期供 VBUS,或 A-device 该供不供、枚举超时。
- 拔插后 VBUS 未放电:残压导致下次会话检测失败/误枚举。
- HNP 未先使能/未挂起就抢主机:跳过 Set Feature 授权和 suspend,协议状态错乱。
- 切换时 PHY/端点未重配:同一 FIFO/端点从 device 切 host 未复位,收发包异常。
- SRP 脉冲时序不符:数据线/VBUS 脉冲宽度、阈值不对,A-device 检测不到。
- 供电能力不足:A-device 带功耗大的外设(硬盘)时 VBUS 跌落/复位。
- 超时处理缺失:OTG 有大量会话/挂起/连接超时,软件不处理会卡在中间态。
- host/device 栈状态残留:角色换回后旧枚举状态/地址未清。
- CC 与数据角色绑定假设:PD 允许供电和数据角色解耦,不能用「谁供电谁当主机」一概而论。
- ID/CC 抖动:插入瞬间抖动导致角色来回切,需去抖/迟滞(见 PinMux/GPIO)。
相关与延伸
设备侧枚举见 USB 端点与枚举;PHY 见 UTMI/ULPI;现代口角色/供电见 Type-C 与 PD;插入去抖见 GPIO 去抖。
总结
USB OTG 让一个口成为双角色设备:Micro-OTG 用 ID 引脚接地与否把插入方分为默认主机并负责 VBUS 的 A-device 和默认设备的 B-device,同一 PHY 与 host/device 双控制器据此复用切换;为省电定义了 SRP(设备在无电时发数据线/VBUS 脉冲请求主机开 VBUS)、为不插拔交换主机定义了 HNP(主机先授权并挂起总线、设备再接管复位枚举,但供电责任始终留在 A-device),会话结束要对 VBUS 放电;在 Type-C 上没有 ID 脚,角色与供电由 CC 的 Rp/Rd/DRP 乃至 PD 独立协商——ID/CC 判反、VBUS 供放责任错、跳过 suspend/HNP 授权和切换时不重配 PHY 端点是四大坑。