串口与串行链路
698 串行链路有两层:原始串口字节流(SerialChannel)和链路时序适配(SerialLinkChannel)。两者都必须经过。
SerialChannel
头文件:<dlt698/transport/serial.hpp>。仅在 DLT698_BUILD_TRANSPORT=ON 时提供。
open同步打开并配置串口,后续读写由运行时驱动。device是 Windows COM 名称或 POSIX 设备路径,例如COM3、/dev/ttyUSB0。Windows COMn 自动使用设备命名空间兼容高编号。- 默认 9600/8E1。
- 失败返回错误,失败时会自动释放已打开的端口。
SerialChannel 不添加 FE 前导,也不切换 RS-485 方向。写完成表示全部交给驱动,不等价于物理线路已经排空。
SerialLinkChannel
头文件:<dlt698/transport/serial_link.hpp>。
SerialLinkChannel 不依赖 Asio,在 core 里,DLT698_BUILD_TRANSPORT=OFF 时也能用——可以直接包 MemoryChannel 做确定性测试。
它做什么
- 只接受恰好一个含校验的完整帧。
async_write不接受半帧或多帧拼接。 - 发送时添加四个 FE,然后按真实排空或软件估算的输出时间,保留至少 33 位的字符间隔。
- 最近一次接收之后才开始发送的,也要延后 33 位。
- 队列预算包括 FE。
- 读取保留 FE,不剥离,由
FrameStreamDecoder处理。
参数一致性
SerialLinkOptions::bits_per_character 是含起始、数据、校验、停止位的总位数,必须与实际串口配置一致。9600/8E1 对应 11 位。
非整数停止位(如 1.5)按向上取整配置位数。
波特率和每字符位数共同决定 33 位间隔的实际时间。配置错误会导致时序不对,表现为 sporadic 校验错误或丢帧。
RS-485 方向控制
SerialLinkOptions 提供两个可选的驱动 hook:
set_transmit(bool)幂等设置方向。true进入发送,false回到接收。async_drain(handler)由驱动确认最后停止位已经发出,再调用完成回调。可以从其他线程完成。
配置了 set_transmit 却没有 async_drain 时,wrap 抛 std::invalid_argument。
async_drain 的回调可以在其他线程调用,说明驱动是异步完成排空确认的。
有排空 vs 只估算
只用估算时,不能保证 USB 缓冲、硬件流控或特定适配器的时序正确。
带流控或需要严格排空的设备应接入 async_drain。
关闭时 SerialLinkChannel 会取消定时器和队列,并尽力恢复接收方向。驱动排空失败时不重放数据。
完整接线
示例中的 session 是 shared_ptr,必须由应用持有到最后。排队任务不会永久保活 Session;序列化适配器和原始通道都是共享所有权,销毁适配器会同时关闭原始通道。
在内存链路上验证
SerialLinkChannel 可以直接包 MemoryChannel,不需要真实硬件就能验证 FE 前导和 33 位间隔:
完整示例见第一个程序。
验证状态
当前证据为虚拟时间/内存链路模拟,以及本机串口参数配置和打开失败路径。真实串口收发与 RS-485 硬件互操作尚未验证。
现场部署前请自行完成硬件时序测量。相关测试状态见协议覆盖范围。