两台开发板的硬件序列号完全相同,如何使用 ADB 连接其中的一台?
在开发板调试或批量测试过程中,有时会遇到这样的情况:多块开发板使用了相同的出厂镜像,导致它们的硬件序列号完全相同。此时执行 adb devices,可能会看到两台设备显示为同一个序列号,使用 adb -s <serial> 无法稳定地指定目标设备。
本文记录一种不需要重新刷机、可以直接区分 USB 设备的方法:使用 ADB 的 transport_id 选择具体连接。
问题背景
设备序列号通常被 ADB 用作设备标识。如果两台设备的序列号相同,ADB 就无法仅通过这个序列号区分它们,例如:
text
error: more than one device/emulator
这种情况通常是由以下原因造成的:
- 开发板厂商使用了相同的系统镜像;
- 出厂流程没有为每块板烧录唯一的序列号;
- 序列号相关的分区或设备树配置被复制到了另一块板上。
虽然硬件序列号相同,但两台设备连接到电脑的 USB 物理端口通常不同。ADB 可以为每个当前连接分配一个 transport_id,用于在同一序列号的设备之间进行选择。
查看设备的 USB 路径和 transport ID
执行:
bash
adb devices -l
示例输出如下:
text
List of devices attached
8b23... device usb:1-1.2 product:board_x model:board_x device:board_x transport_id:1
8b23... device usb:1-1.4 product:board_x model:board_x device:board_x transport_id:2
其中:
8b23...:设备序列号,两台设备相同;usb:1-1.2、usb:1-1.4:设备在当前 USB 拓扑中的物理路径;transport_id:1、transport_id:2:ADB 为当前连接分配的传输 ID。
USB 路径可以帮助我们确认哪一个电脑端口对应哪一块开发板,真正执行命令时则使用 transport_id。
使用 transport ID 连接指定设备
假设目标设备的 transport_id 是 1,可以执行:
bash
adb -t 1 shell
进入的就是第一块开发板,而不是由 ADB 在同序列号设备中随机选择。
也可以直接对指定设备执行命令:
bash
# 查看第一块开发板的型号
adb -t 1 shell getprop ro.product.model
# 查看第二块开发板的 Android 版本
adb -t 2 shell getprop ro.build.version.release
# 从第一块开发板拉取日志
adb -t 1 pull /sdcard/log.txt ./board-1-log.txt
# 仅向第二块开发板安装 APK
adb -t 2 install app-debug.apk
只要在每条 ADB 命令中带上 -t <transport_id>,就可以避免同序列号设备之间的歧义。
为什么不能只使用序列号?
通常我们会这样指定设备:
bash
adb -s 8b23... shell
但当多个设备拥有相同的序列号时,这个参数无法表达"同一序列号下的第几台设备",因此可能出现设备选择错误或 more than one device/emulator 报错。
这种情况下可以把设备选择方式改为:
bash
adb -t <transport_id> shell
注意事项
transport_id 不是永久不变的
transport_id 通常由 ADB Server 在设备连接时分配。设备拔出后重新插入,或者重启 ADB Server 后,ID 可能发生变化。因此不要把 transport_id 当作开发板的永久编号。
每次重新连接设备后,建议重新执行:
bash
adb devices -l
确认最新的 transport_id。
物理 USB 端口最好保持固定
如果测试脚本需要长期区分多块开发板,可以将开发板固定插在 USB Hub 或电脑的固定端口上。这样 usb:1-1.2 这类物理路径通常可以作为识别依据,再动态解析当前对应的 transport_id。
不要混淆 USB 路径和 transport_id
例如:
text
usb:1-1.2
transport_id:1
前者描述 USB 拓扑位置,后者是 ADB 当前连接的传输编号。连接设备时使用的是:
bash
adb -t 1 shell