那adb 也是一个串口吗?感觉像啊不是,那为什么会跟ttyGS 抢呢?
2026/8/6 21:25:46 网站建设 项目流程

你的直觉非常敏锐!ADB 确实“用起来像串口”,但它在底层“绝对不是串口”!

它们之所以会“抢”,是因为它们在争夺 USB 芯片内部有限的硬件资源(插槽与管道)

下面为你拆解:为什么 ADB 用起来像串口?以及它们到底在抢什么?


一、 ADB 是串口吗?(为什么用起来那么像?)

答案:不是串口。

  • 为什么用起来像?
    因为你用adb shell敲命令时,界面和串口终端(如 SecureCRT / Putty)一模一样,都是打字、回车、返回结果,数据也是流式传输的。
  • 底层的本质区别:
    • ttyGS(CDC-ACM):是符合国际标准的硬件级虚拟串口(遵循 USB CDC-ACM 协议)。它在内核里会生成标准的串口设备节点(如/dev/ttyGS2),任何 C 语言/Java 串口库都能直接 open/read/write 它。
    • ADB(FunctionFS):是 Google自定义的一套私有网络协议(类似于一个运行在 USB 上的 Mini 版 TCP/IP 协议)。它在内核里使用的是ffs.adb(FunctionFS),必须运行一个名为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_storage(U盘)需要占用2 个管道
  • 冲突原因:当旧脚本试图把 U盘 + ADB + 串口 + 网卡全部挂载进去时,芯片的物理管道不够用了!内核直接拒绝写入,抛出Device or resource busy
3. 抢物理主机的“USB 设备描述符”

当 USB 线插进电脑/母 设备 时,母 设备 必须知道这条线里包含了什么功能:

  • 如果子 设备 告诉母 设备:“我只有 ADB”;
  • 后来子 设备 又想加上串口,但没有先断开线(pullup D-)重新汇报
  • 母 设备 的驱动就会错乱,不知道该把数据发给 ADB 还是发给串口,导致整个 USB 接口假死。

💡 总结:我们改的代码是如何让它们“和平共处”的?

你修改后的acm,adb组合脚本,做到了以下三点和谐共处:

  1. 明确分工(不抢插槽):强制规定f1专门给acm.gs2(串口)f2专门给ffs.adb(ADB)
  2. 剔除多余功耗(不抢管道):把没用的mass_storage(U盘)剔除掉,省下硬件管道给串口和 ADB 享用,再也不会触发Device busy
  3. 规范汇报(打包成复合设备):向母 设备 汇报:“我是一个复合设备(Composite Device),内部包含了 1 个串口 + 1 个 ADB”,母 设备 识别后,就会同时给子 设备 分配独立的串口通道和 ADB 通道!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询