Appearance
通信与协议设计(V10)
通信设计回答“通信模块应该怎样工作”。它不是所有通信问题的默认入口。V10 先判断当前任务是查现状、修回归、做小改,还是确实需要重新设计协议和连接生命周期。
1. 先判断是否需要完整通信设计
| 当前任务 | 推荐入口 |
|---|---|
| “当前为什么收不到数据?” | 通信证据包 + Bug 调查 |
| “这条命令现在从哪发出去?” | Read-Only Trace |
| “超时从 2 s 改为 3 s,规则已明确” | Execution / BehaviorPatch |
| “昨天改后才开始断线” | Temporal Regression |
| 新设备接入 / 新协议 / 角色和恢复规则未知 | 本页完整通信设计 |
不要因为代码里出现 SerialPort、TcpClient 或 VISA,就自动重新设计整个通信层。
2. 设计输入:事实优先从材料确认
优先从协议文档、示例报文、代码、日志、抓包和设备手册确认:
- 上位机与设备角色;
- 串口/TCP/UDP/VISA/SDK 等介质;
- 帧头、长度、命令字、字段、校验、字节序;
- 请求/响应还是主动上报;
- 设备启动、停止、查询、配置和恢复行为;
- 现场断线、重启、掉电和人工干预条件;
- 可用的 Fake、Replay、模拟器和真机条件。
只有会改变最终通信行为、且材料无法回答的问题才进入 Discovery Frontier。
3. 设计内容
| 方向 | 必须说明 |
|---|---|
| 通信角色 | 谁发起连接,谁主动发送,谁拥有重连 |
| Session Owner | 谁创建、复用和释放唯一设备会话,是否允许并发会话 |
| 连接生命周期 | 打开、握手、运行、停止、断开、释放 |
| 消息/帧结构 | 仅按当前协议实际存在的头、长度、命令、序号、校验、结束符等描述 |
| 组包拆包 | 仅流式协议需要说明半包、粘包、多帧和异常字节处理 |
| 字节序与量纲 | 协议涉及二进制/缩放时说明 Endian、Raw/工程值、单位和精度 |
| 超时与重试 | 哪些操作允许重试,重试是否安全、是否幂等 |
| 心跳与重连 | 谁触发,旧任务是否退出,重连后状态怎样恢复 |
| 请求响应关联 | 当前协议实际使用的命令字、序号、事务 ID、等待队列或串行规则 |
| 原始证据 | TX/RX、解析失败、超时、错误队列、状态和时间戳 |
| 停止释放 | Cancellation、关闭顺序、Dispose、事件解绑 |
| 验证 | 先做通用生命周期验证,再按协议类型追加 focused 样本 |
4. 一条硬规则:不要偷偷打开第二设备会话
同一设备通常应有明确的 Session Owner:
text
UI / Workflow
→ Application / Device Service
→ 一个受控通信 Session
→ Serial / TCP / VISA / SDK诊断、恢复、状态查询应优先复用现有会话或现有设备服务。除非协议和设备明确允许,不要为了“读一下状态”另开第二个串口、SCPI 或 SDK 会话。
典型风险:
- 旧会话仍在读,新会话抢占设备;
- 第二客户端改变设备内部状态;
- 恢复逻辑与正常通信并发发送;
- Stop 后旧接收任务没退出,Reconnect 又启动一套任务。
详见 线程与资源生命周期。
5. 通信状态与业务后果必须分开
通信层可以有:
text
Disconnected
Connecting
Connected
Running
Reconnecting
CommunicationError但 CommunicationError 不等于业务必须 FaultStop。
例如一次超时可能是:
- Information:仅记录;
- Advisory:提示操作员;
- AlarmOnly:报警但流程继续;
- InterlockFault:必须停止/阻断。
业务后果必须由项目规则决定,不从“异常”二字自动推导。详见 行为与告警语义。
6. 超时与重试要先回答“重复执行安全吗”
重试前快速确认:
text
命令是查询还是动作?
重复发送是否幂等?
设备可能已经执行但响应丢失吗?
需要先查询状态再重试吗?
用户是否需要知道发生过重试?“写参数”“启动”“运动”“高压输出”等动作不能套用普通查询命令的自动重试策略。
7. Protocol-Shaped Verification:先通用,再按协议族追加
7.1 所有通信实现都应验证的生命周期
| 场景 | 期望结果 | 证据 |
|---|---|---|
| 正常连接/打开 | 状态与 owner 一致,不重复创建资源 | lifecycle log |
| 正常收发/调用 | 请求与响应可追溯 | TX/RX 或 SDK call/result |
| 超时 | 产生规定通信结果,不擅自升级业务后果 | timeout evidence |
| 断开/停止 | Pending I/O 可退出,后台任务和事件订阅被释放 | stop evidence |
| 重连/恢复 | 旧会话已结束,只存在一套有效 Session/receive loop | session evidence |
| 取消 | Cancellation 能传播到真正拥有 I/O 的边界 | timeline / task state |
7.2 自定义流式二进制协议
只有这类协议才重点追加:
- 半包;
- 粘包;
- 多帧连续到达;
- 帧头错位/异常字节;
- 若协议定义 CRC/Checksum,再增加校验错误样本;
- 若协议有 Sequence/Transaction ID,再增加乱序、重复和关联错误。
7.3 Modbus
重点验证:
- 功能码与异常码;
- 寄存器地址/数量边界;
- 字节序、字序和数据类型换算;
- 请求/响应关联;
- 超时、断线和重连后的状态。
不因为底层是 TCP 就机械增加“应用层粘包测试”;应验证实际 Modbus 实现的消息边界和 transport 行为。
7.4 SCPI / VISA / 文本仪器协议
重点验证:
- 命令顺序;
- query/action 的语义;
- 终止符和响应读取规则;
*OPC?、状态寄存器或厂商定义完成条件(仅实际使用时);- error queue;
- Session Owner 与恢复路径;
- 设备可能残留的模式/输出/触发状态。
不要为了“测试完整”给 SCPI 强行增加 CRC、二进制帧头和粘包矩阵。
7.5 厂商 SDK
重点验证:
- SDK 返回码/异常;
- handle/session 生命周期;
- callback 线程与取消;
- 重连是否产生旧 callback/旧 handle 残留;
- SDK 行为与业务后果之间的映射。
底层传输细节若被 SDK 封装且项目无法观察,不虚构 CRC/帧边界测试。
8. Bug 优先 Replay,不必每次拿真机碰运气
如果已经有现场 HEX、SCPI 或 TCP 日志,优先转成:
text
Captured input
→ parser / protocol state
→ Fake or Replay
→ deterministic result真实设备用于验证设备端行为和最终验收,不是每个协议问题的第一反馈环。
9. 输出物按任务缩放
新协议 / 新设备
可以输出:
- 协议说明;
- Session/lifecycle 设计;
- 通信状态图;
- 时序;
- 异常/恢复策略;
- 按当前协议类型裁剪后的测试矩阵。
已有系统局部修改
不需要重新生成整套设计,只保留本次变化:
text
CurrentBehavior
TargetBehavior
AffectedProtocolRule
SessionImpact
Evidence
VerificationLevel10. 验证等级
- 纯解析/字段规则:通常 V2 focused parser tests;
- 连接、断线、重连、Session owner:V2/V3;
- 通信异常改变试验状态或联锁:至少 V3 + WorkflowSmoke;
- 发布/广泛协议兼容:V4。
软件侧验证与真机权限分开;需要现场设备但尚未执行时写 HardwarePending,真实高压、运动、气路等动作仍需人工授权。
对应能力
| 项目 | 内容 |
|---|---|
| 推荐 Skill | 04-protocol-designer、05-communication-expert;已有 Bug 可由 09/10 接管 |
| 推荐模板 | 串口/TCP 通信任务模板、通信证据包 |
| 资源边界 | 线程与资源生命周期 |
| 验证 | AI 辅助测试与回归 |
一句话原则
新协议才做完整通信设计;已有问题先找证据和最短反馈环,验证矩阵由当前协议形态决定,通信异常的业务后果也不能靠异常类型自动猜。