那adb 也是一个串口吗?感觉像啊不是,那为什么会跟ttyGS 抢呢?

📅 2026/8/6 21:25:52
那adb 也是一个串口吗?感觉像啊不是,那为什么会跟ttyGS 抢呢?
你的直觉非常敏锐ADB 确实“用起来像串口”但它在底层“绝对不是串口”它们之所以会“抢”是因为它们在争夺 USB 芯片内部有限的硬件资源插槽与管道。下面为你拆解为什么 ADB 用起来像串口以及它们到底在抢什么一、 ADB 是串口吗为什么用起来那么像答案不是串口。为什么用起来像因为你用adb shell敲命令时界面和串口终端如 SecureCRT / Putty一模一样都是打字、回车、返回结果数据也是流式传输的。底层的本质区别ttyGSCDC-ACM是符合国际标准的硬件级虚拟串口遵循 USB CDC-ACM 协议。它在内核里会生成标准的串口设备节点如/dev/ttyGS2任何 C 语言/Java 串口库都能直接 open/read/write 它。ADBFunctionFS是 Google自定义的一套私有网络协议类似于一个运行在 USB 上的 Mini 版 TCP/IP 协议。它在内核里使用的是ffs.adbFunctionFS必须运行一个名为adbd的守护进程才能解析数据。二、 既然 ADB 不是串口为什么会和ttyGS抢呢它们在底层并不是“业务上打架”而是在抢USB 芯片的 3 种底层硬件资源1. 抢 ConfigFS 的“乐高插槽” 导致File exists报错在 Linux USB 复合设备Composite Device中插槽编号是有限的f1,f2,f3单 ADB 脚本说“我要把 ADB 放在f1插槽”串口脚本说“我也要把ttyGS2串口放在f1插槽”结果后执行的脚本发现f1已经被占了直接抛出symlink() failed: File exists崩溃2. 抢芯片内部的“硬件传输管道”Endpoints / 端点导致Device busy报错联发科 MT8189 芯片内部的物理传输管道Hardware Endpoints数量是有限的比如只有 8 个 IN/OUT 管道ttyGS2串口需要占用3 个管道数据输入、数据输出、中断响应ffs.adb需要占用2 个管道数据输入、数据输出mass_storageU盘需要占用2 个管道。冲突原因当旧脚本试图把 U盘 ADB 串口 网卡全部挂载进去时芯片的物理管道不够用了内核直接拒绝写入抛出Device or resource busy3. 抢物理主机的“USB 设备描述符”当 USB 线插进电脑/母 设备 时母 设备 必须知道这条线里包含了什么功能如果子 设备 告诉母 设备“我只有 ADB”后来子 设备 又想加上串口但没有先断开线pullup D-重新汇报母 设备 的驱动就会错乱不知道该把数据发给 ADB 还是发给串口导致整个 USB 接口假死。 总结我们改的代码是如何让它们“和平共处”的你修改后的acm,adb组合脚本做到了以下三点和谐共处明确分工不抢插槽强制规定f1专门给acm.gs2串口f2专门给ffs.adbADB。剔除多余功耗不抢管道把没用的mass_storageU盘剔除掉省下硬件管道给串口和 ADB 享用再也不会触发Device busy。规范汇报打包成复合设备向母 设备 汇报“我是一个复合设备Composite Device内部包含了 1 个串口 1 个 ADB”母 设备 识别后就会同时给子 设备 分配独立的串口通道和 ADB 通道