嵌入式背板通信:为什么我们从 UART 换成了 CAN-FD
约 2 分钟 阅读 28做仪器背板的人多半默认"控制命令走 UART"——我们最初也这么设计,然后在一次架构评审里把它整个推翻了。这篇记录推翻的过程和理由。
控制面要解决什么
一台模块化仪器主机:主控实时核(R5F)要和 10 张仪器卡的 MCU 双向通信——命令下发、配置、状态回传、固件升级分片。数据量不大(每卡 1k cmd/s 量级),但有两个硬要求:
- 不能丢、不能错:仪器命令错一个字节,可能就是量程切错、激励加错;
- 故障隔离:一张卡抽风,不能把其余 9 张卡的通信带走。
旧方案:LVDS 星型 + 裸 UART
最初的设计是每槽分配 LVDS 差分对,卡上 UART 直连,CRC-8 校验。看起来够用,但评审时摆出事实:
- 异步串口没有硬件 ACK、没有自动重传——错了只能靠上层超时重试;
- CRC-8 只检不纠,链路层健壮性跟数据面(8b/10b + CRC16 + 流控)严重不对称;
- 每槽要占 2~4 对 LVDS,10 槽就是 20~40 对差分线,挤压本就紧张的数据面引脚。
一句话:把最不可靠的链路层,用在了最不能出错的业务上。
为什么是 CAN-FD
换型候选里,CAN-FD 几乎是为这个场景定制的:
| 特性 | 对控制面的意义 |
|---|---|
| 硬件 ACK + 自动重传 | 链路层自己保证送达,上层不用补窟窿 |
| 多主仲裁 + 位填充 | 10 卡共总线无需轮询调度 |
| 错误状态自隔离(bus-off) | 坏节点自己退出总线,天然满足故障隔离 |
| 车规级生态 | 收发器/调试工具/工程经验全部现成 |
拓扑上做两段(CAN0/CAN1 各挂约 5 槽):一段物理短路只影响半台机器,不会全瘫。副产品是释放了原来控制面占的全部 LVDS 对——差分对预算从"超支"变"宽裕"。
怎么承载我们的协议
控制面跑的是自研 Keel IPC 帧(24B 头 + ≤256B 载荷 + CRC-8),比 CAN-FD 单帧的 64B 大,所以加一层分段传输:
- 整帧按 59B 分页,每段 = 5B 段头 + 数据,收端按段序号重组(≤8 段);
- 完整性双保险:CAN 帧自带 CRC15/17,重组完成后再验 IPC 头 CRC-8;
- 11bit CAN ID 直接编码路由:
优先级 | 槽号 | 方向,硬件仲裁器顺手把优先级调度也做了。
诚实声明与退路设计
背板多节点条件下的误码率我们还没实测——这是后续里程碑第一个月的头号行动项。但设计时就把"测不过怎么办"想好了,降级阶梯一次到位:
5M FD → 2M FD → 1M 经典 CAN(纯软件退守,硬件零改动)→ M-LVDS/RS485 兜底总线
配套选型约束:CAN-FD 收发器必须选 FD-SIC 兼容型号(主动抑制多 stub 振铃),PCB 一次到位、速率可退。架构不能被单点绑死——这是这次评审最大的收获。
边界纪律
最后明确两条"什么不走 CAN":
- 触发不走 CAN——走 TRIG 硬线,纳秒级确定性;
- 波形/采样数据不走 CAN——走 LVDS 数据面,CAN 只跑命令与状态,流量占比控制在 20% 以内。
总线选型不是比峰值速率,是比故障域隔离和链路层对称性。这两条想清楚,答案自己就出来了。