纯 adb 绑 UDC 增加 其中UDC 是什么?
在 Linux 内核和 Android 系统中,UDC是一个极其核心的硬件术语:
UDC=USBDeviceController(USB 设备控制器 / 从机硬件控制器)
一、 形象的比喻(汽车发动机与发车)
如果把子 设备 的 USB 系统比作一辆汽车:
- ConfigFS(
/config/usb_gadget/g1):是汽车的设计图与中控台(里面配置了 VID/PID、CD-ROM 光盘、ADB 调试、ACM 串口等软参数)。 - UDC(如
11201000.usb0):就是汽车的物理发动机(SoC 芯片内部控制 USB 物理 D+/D- 针脚电平的真正硬件)。 - 绑定 UDC(
write /config/usb_gadget/g1/UDC 11201000.usb0):相当于拧钥匙点火、踩下油门发车!- 这一步执行后,USB 硬件芯片才会正式通电、拉高 D+ 引脚信号,母 设备 才能在物理上感知到有设备插入!
- 解绑 UDC(
write /config/usb_gadget/g1/UDC none):相当于挂空挡、熄火(断开 D+ 信号,物理断连)。
二、 为什么你的日志里 UDC 叫11201000.usb0?
在 MT8(联发科芯片)内部:
11201000是这块芯片内部 USB 控制器硬件在物理内存里的寄存器基地址(0x11201000)。usb0代表第 0 号 USB 物理接口。11201000.usb0就是这块USB 发动机的“硬件身份证号”。
三、 什么是 Change 2 里提到的“纯 adb 绑 UDC 增加限制(防抢绑)”?
在原生 Android 系统里,有一个默认的配置文件(init.usb.configfs.rc)。
没有加限制前(存在“抢绑”引发的冲突):
- 原生 Android 发现
sys.usb.config=adb,它的默认脚本会跑去把“发动机”(UDC)启动了,但此时只绑定了f1=adb一个功能。 - 几毫秒后,MTK 的 POS 专用脚本也启动了,准备绑定
f1=mass_storage, f2=adb, f3=acm三个功能,也跑去启动“发动机”(UDC)。 - 两套脚本抢着去启动 UDC 发动机,导致 USB 状态机发生竞态冲突(UDC 抢绑),导致串口或 ADB 随机卡死!
加了限制后(Change 2 做的事情):
我们在原生 AOSP 的“纯 ADB 脚本”条件里,加了一个锁:property:vendor.usb.acm_enable=0(只有当没有开启 设备 串口通讯时,纯 ADB 脚本才允许去绑 UDC)。
- 效果:当 设备串口开启时(
acm_enable=1),原生 AOSP 脚本自动退避,交由 MTK 的三合一脚本独占、干净地去一次性绑定 UDC,彻底根除了上电时两套脚本抢绑 UDC 导致的死锁!