UART 传输

FDomain 可通过物理串行端口 (UART) 运行,使开发者能够与没有有效网络或 USB 连接的 Fuchsia 设备进行交互和调试。

概览

UART 传输通过异步串行线路(例如 Linux 上的 /dev/ttyUSB0)运行 FDomain 协议,该线路连接到 Fuchsia 目标设备的串行控制台端口(在 /dev/class/serial/ 下公开)。

通信使用 ResendSP 滑动窗口成帧协议以高线路速率(默认为 1,000,000 波特)运行,该协议通过校验和、确认和跨设备重新启动的会话跟踪提供可靠的双向传送。

前提条件

主机串行端口权限

在 Linux 主机上,访问 TTY 字符设备(例如 /dev/ttyUSB0)需要加入 dialout 群组:

sudo usermod -a -G dialout $USER

您必须退出并重新登录(或运行 newgrp dialout),群组成员资格才能生效。

在 ffx 中启用 UART 目标发现

默认情况下,ffx 目标发现功能会监控 mDNS 和 USB 发现流。如需使 UartWatcher 子系统能够监控活跃的 UART 连接并在 ffx target list 中列出这些连接,请将 connectivity.enable_uart 设置为 true:

ffx config set connectivity.enable_uart true

目标硬件配置

在物理硬件平台(例如使用 DesignWare 8250/APB UART 控制器的开发板)上,高速串行速率(1,000,000 波特)使用除数锁存分数 (DLF) 寄存器进行校准,以最大限度地减少位时序误差。

由于单端口目标会在内核控制台和用户空间服务之间共享物理串行线路,因此,若要通过 UART 启用 ffx,需要通过内核命令行参数(例如,在 local/BUILD.gn 开发者替换中)将串行端口所有权移交给用户空间 FDomain UART 驱动程序 (fdomain-uart-driver):

  • dev.fdomain.uart=true:使目标端 fdomain-uart-driver 组件能够发现并绑定到 /dev/class/serial/ 中的串行端口。
  • dev.fdomain.uart.baud=1000000:配置目标串行端口波特率。
  • kernel.serial=none:停用 Zircon 内核串行控制台,以便内核调试输出不会与二进制 ResendSP 帧发生冲突。
  • console.shell=false:停用用户空间交互式串行控制台 shell (console.cm)。

连接管理

与支持自动后台枚举的网络或 USB 接口不同,串行端口是共享的物理资源,没有标准的总线发现机制。ffx uart 工具提供了明确的子命令,用于管理连接生命周期并确保主机工具之间的互斥。

连接到目标

如需与实体设备建立 UART 连接,请执行以下操作:

ffx -t /dev/ttyUSB0 uart connect

(您也可以添加 uart: 前缀,例如 ffx -t uart:/dev/ttyUSB0 uart connect)。

ffx uart connect 默认为 1,000,000 波特。如果开发板配置需要,您可以指定自定义波特率:

ffx -t /dev/ttyUSB0 uart connect --baud 115200

连接时: 1. 该工具会获取串行设备上的独占文件锁 (flock),以防止其他进程并发访问。2. 它会以原始模式配置 TTY,其中包含 8 个数据位、1 个停止位、无奇偶校验 (8N1) 和指定的波特率。 3. 它会生成 ffx-uart-driver 后台守护程序,以多路复用 FDomain 流量。 4. 连接元数据记录在 ffx 共享数据目录 (ffx_uart/) 下。

通过 UART 运行命令

连接后,您可以使用 uart: 地址前缀运行任何针对 UART 设备的标准 ffx 命令:

ffx -t uart:/dev/ttyUSB0 target echo
ffx -t uart:/dev/ttyUSB0 log

探测连接健康状况

如需验证物理串行端口是否响应并与目标的 FDomain UART 服务通信,请执行以下操作:

ffx -t /dev/ttyUSB0 uart probe

probe 命令会执行以下检查: * 如果后台驱动程序已处于活跃状态,则会验证驱动程序进程的健康状况并报告当前状态。 * 如果没有活跃的驱动程序,它会临时打开端口,与目标执行协议协商握手,测量往返时间 (RTT),并报告服务是否响应。

列出有效连接

如需查看所有活跃的 UART 驱动程序实例及其关联的设备,请运行以下命令:

ffx uart list

输出示例:

TARGET                         PID      BAUD     PROTOCOL   STATUS
/dev/ttyUSB0                   12345    1000000  ResendSP Connected

目标发现

启用 connectivity.enable_uart 且 UART 后台驱动程序处于活动状态时,ffx 会自动发现目标:

ffx target list

输出示例:

NAME                      SERIAL          TYPE           STATE      ADDRS/IP              MANUAL    RCS
fuchsia-54b7-e1d8-7af6    1234567890ab    minimal.x64    Product    [uart:/dev/ttyUSB0]   N         Y

ffx 通过监控 ffx-uart-driver 写入的连接元数据,被动发现 UART 目标。目标设备的节点名称和序列号由驱动程序在连接时获取并存储在元数据中,这样,发现功能便可以立即检测并枚举已连接的设备,而无需争用物理串行端口。如果同一设备还通过 USB 或网络连接,ffx 会通过匹配硬件序列号将这些地址合并到单个目标条目下。

监控状态和指标

如需检查活跃连接的实时传输统计信息,请执行以下操作:

ffx -t /dev/ttyUSB0 uart status

此命令会查询驱动程序守护进程的本地控制套接字和元数据,以报告操作详细信息,包括: * 目标路径、16 字符目标 ID、守护进程 PID 和驱动程序日志文件路径。* 发现的目标节点名称和硬件序列号。 * 连接状态、配置的波特率和活跃协议 (ResendSP)。 * 估计的往返延迟时间 (Estimated RTT)、重新传输次数、CRC 校验和错误、连接中断和握手失败。 * 上次读/写活动时间戳、传出队列长度、停滞检测警告以及目标 (Last Target Error) 报告的最新通道错误。

正在断开连接

如需终止后台驱动程序并释放串行设备锁,请执行以下操作:

ffx -t /dev/ttyUSB0 uart disconnect

释放连接后,串行设备便可用于其他用途,例如交互式调试控制台或固件刷写。

重新连接

如需使用保存的元数据重启后台驱动程序(例如,在电缆断开连接或出现暂时性主机问题后),请运行以下命令:

ffx -t /dev/ttyUSB0 uart connect --reconnect

架构和框架

+-------------------------------------------------------------+
|                        Host Machine                         |
|                                                             |
|   +------------+        +-------------------------------+   |
|   |  ffx CLI   | <----> | ffx-uart-driver (Daemon)      |   |
|   +------------+ (UNIX  +-------------------------------+   |
|                  Socket)                |                   |
|                                         | (ResendSP Frames) |
|                                         v                   |
|                              [/dev/ttyUSB0] (flock)         |
+-------------------------------------------------------------+
                                          |
                                          | Physical Serial Cable
                                          | (1,000,000 Baud, 8N1)
                                          v
+-------------------------------------------------------------+
|                       Target Hardware                       |
|                                                             |
|                [/dev/class/serial/<instance>]               |
|                                 |                           |
|                                 v                           |
|               +-----------------------------------+         |
|               | fdomain-uart-driver -> RCS        |         |
|               +-----------------------------------+         |
+-------------------------------------------------------------+

ResendSP 帧协议

UART 传输使用 ResendSP 帧协议通过面向原始字节的串行链路流式传输数据: * 滑动窗口 Go-Back-N:支持流水线传输多达 32 个传输中的帧,以最大限度地提高本地串行电缆和高延迟桥接链路的带宽利用率。 * 流控制和背压:累积确认和每个通道的流控制可防止嵌入式目标上的缓冲区溢出。* 完整性校验和:13 字节帧头上的 8 位标头校验和(HdrChk,CRC-8 多项式 0x07)以及帧载荷上的 32 位 IEEE 802.3 CRC (CRC-32) 可检测由电线噪声引起的传输错误。 * 重新启动检测:在通道 0 握手期间协商的会话令牌允许主机和目标检测重置并自动重新同步流状态,而无需重新启动对等端。

问题排查

  • 打开 /dev/ttyUSB0 时权限遭拒:请确保您的用户账号位于 dialout 群组 (id $USER) 中,并验证设备权限。
  • 设备忙(EWOULDBLOCK / EAGAIN,在 connect 期间):另一个进程持有 TTY 设备的排他锁。确认该端口上没有打开其他串行终端程序(例如 minicom、screen、picocom)。
  • connect 或 probe 期间握手超时:检查物理 TX/RX 线路是否正确连接,引导加载程序 UART 多路复用器和时钟是否配置为 1,000,000 波特,以及目标是否使用 dev.fdomain.uart=true、kernel.serial=none 和 console.shell=false 启动。