跳到主要内容

CAN自定义协议

本标准旨在为基于 CAN FD 总线的嵌入式系统提供一套可复用的应用层协议设计指南。适用于主从架构或多节点分布式系统中,对数据吞吐量、实时性、可扩展性有明确要求的场景。

1. 范围与目的

本标准规定了基于 CAN FD 物理层与数据链路层的应用层协议设计方法,包括:

  • 协议架构与分层
  • 标识符分配策略
  • 数据帧格式
  • 时间同步机制
  • 传输层协议(分片与重组)
  • 网络管理
  • 错误处理与诊断
  • 测试与验证要求

2. 规范性引用文件

  • ISO 11898-1:2015(CAN FD 数据链路层)
  • CiA 601(CAN FD 应用层设计建议)

3. 术语与定义

术语定义
上行从设备端(MCU、传感器)发往主机端(Linux、PC)的数据流
下行从主机端发往设备端的控制或配置数据流
seq同步序号,用于关联同一周期或同一事务的多帧数据
锚点外部同步事件(如FSIN、软件定时器)产生的时刻标记
分片将超过单帧最大载荷的业务数据拆分为多帧发送
通用头所有业务帧共用的固定头部,包含版本、类型、序号等

4. 协议设计原则

  1. 分层清晰:协议应至少划分为“帧格式层”与“业务载荷层”,便于维护与扩展。
  2. 时间确定性:关键数据应携带硬件时间戳,时间源统一为单调时钟(us级)。
  3. 可扩展性:通过版本号、保留字段、消息类型扩展机制支持未来升级。
  4. 紧凑性:充分利用 CAN FD 64 字节数据场,避免带宽浪费。
  5. 容错性:定义错误标志、降级策略与心跳监控,确保系统可诊断。
  6. 兼容性:若网络中存在传统 CAN 节点,CAN FD 帧须禁用 BRS 或使用独立 ID 空间。

5. 物理层与数据链路层配置

5.1 位速率选择

  • 仲裁段(Nominal):典型值 500 kbps 或 1 Mbps。用于总线仲裁,应保证所有节点一致。
  • 数据段(Data):典型值 2 Mbps、4 Mbps、8 Mbps。依据线束长度、节点数量、EMC 环境选择,启用 BRS(波特率切换)。

5.2 位时序计算

  • 依据控制器时钟频率(如 STM32G431 的 FDCAN 时钟 170 MHz)计算预分频器、时间片段。
  • 采样点建议:仲裁段 70%~80%,数据段 75%~85%。
  • 同步跳转宽度(SJW)建议设为 1~3,保证抗干扰能力。

5.3 接收过滤

  • 根据节点数量配置硬件过滤器(标准 ID 或扩展 ID 掩码)。
  • 开发阶段可设置为接收全部 ID(过滤器数量为 0);量产阶段按 ID 段过滤,减少无关中断。

5.4 自动重发

  • 高可靠性场景建议开启自动重发(AutoRetransmission = ENABLE)。
  • 若关闭,则应用层须实现超时重传机制。

6. 标识符(ID)规划

6.1 ID 类型选择

  • 标准 ID(11-bit):节点数 ≤ 128,消息类型较少时使用。
  • 扩展 ID(29-bit):多节点、多功能、需要嵌入节点地址或功能码时使用。

6.2 ID 分段策略

将 ID 空间按优先级、方向、功能划分。例如:

位域长度含义
优先级3-bit0(最高)~7(最低)
方向1-bit0=上行,1=下行
功能码4-bit具体消息类型
节点地址3-bit目标或源节点号

或使用更简单的分段:

  • 上行:0x100 ~ 0x17F
  • 下行:0x180 ~ 0x1FF

6.3 预留与扩展

  • 保留 10%~20% ID 空间用于未来扩展。
  • 若使用扩展 ID,保留高位用于设备型号或版本标识。

7. 数据帧格式

7.1 通用头部(8 字节固定)

所有业务帧载荷的前 8 字节采用统一格式:

字节偏移字段类型说明
0proto_veruint8_t协议版本号
1msg_typeuint8_t消息类型(见 7.2)
2flagsuint8_t标志位:bit0=分片,bit1=ACK请求,bit2=错误帧
3hdr_lenuint8_t头长度(固定 8)
4-5sequint16_t同步序号(或事务序号)
6part_idxuint8_t分片索引,从 0 开始
7part_cntuint8_t总分片数,单帧为 1

字节序:小端(Little-Endian)。

7.2 消息类型(msg_type)定义

类型值方向含义
0x01上行同步锚点
0x02上行IMU 数据
0x03上行编码器数据
0x04上行系统状态
0x81下行控制命令
0x82下行参数配置
0x8F下行链路测试(Ping)
0xFF任意厂商调试

7.3 业务载荷定义

每种消息类型紧跟通用头定义其私有载荷。设计原则:

  • 使用紧凑型结构(__attribute__((packed))#pragma pack(1)
  • 整数采用缩放表示(如 s16 表示角速度,精度 0.01 dps)代替浮点,节省带宽
  • 预留 2~8 字节保留字段供后续扩展
  • 总载荷长度建议不超过 64 字节(CAN FD 数据场最大值)

示例(IMU 数据载荷):

struct imu_payload {
uint64_t ts_us; // 采样时间戳(us)
int16_t gyro[3]; // 陀螺仪,单位 mdps
int16_t acc[3]; // 加速度计,单位 mg
uint8_t src; // 传感器源
uint8_t quality; // 质量标志
uint8_t reserved[2]; // 对齐保留
};

7.4 时间戳策略

  • 统一时钟源:所有时间戳使用 MCU 单调时钟(us),避免使用上位机时间戳。
  • 锚点同步:对于周期性外部触发系统,单独发送锚点帧记录触发时刻;数据帧携带各自采样时刻,上位机通过比对获得精确时序。
  • 无锚点系统:可直接在每个数据帧中携带采样时刻。

8. 传输层协议(分片与重组)

当单条业务消息载荷超过 64 字节(CAN FD 最大数据场)时,需进行分片传输。

8.1 分片规则

  • 发送端设置 flags.bit0 = 1
  • part_cnt 记录总分片数
  • part_idx 从 0 递增
  • 所有分片使用相同的 seqmsg_type
  • 分片间隔应尽可能短,避免接收端超时

8.2 重组规则

  • 接收端根据 (seq, msg_type) 维护重组缓冲区
  • 超时未收齐所有分片则丢弃该消息并记录错误(建议超时时间 5~20 ms)
  • 支持乱序到达(根据 part_idx 重组)
  • 重复分片以首次到达为准,后续丢弃

8.3 流控(可选)

对于大文件传输(如固件升级),可定义流控制帧:

  • 接收端发送流控帧通知发送端窗口大小、间隔时间
  • 发送端依据流控参数调节发送速率,防止接收端缓冲区溢出

9. 网络管理

9.1 心跳机制

  • 每个节点周期性(如 10 Hz)发送状态帧(如 SYS_STATUS)
  • 状态帧包含:运行时间、错误标志、供电电压、温度、丢包计数等
  • 主机若超过 N 个周期未收到从机心跳,判定从机离线并触发故障保护

9.2 在线诊断

  • 下行命令支持请求状态立即上报(如 CMD_CTRL 中 cmd_id=0x04)
  • 支持链路测试(Ping/Pong),可用于计算往返时延(RTT)

9.3 负载管理

  • 预先定义数据流优先级,当总线负载超过阈值时,自动降低非关键数据发送频率
  • 优先级顺序建议:同步锚点 > 控制命令 > 关键传感器数据 > 状态 > 非周期配置

10. 错误处理与安全

10.1 错误标志

在状态帧中定义错误位图,至少包括:

  • 传感器 FIFO 溢出
  • 时间戳回退
  • CAN 发送队列满
  • CAN ACK 错误
  • 配置参数非法

10.2 端到端保护

对关键控制命令(如电机启停、参数写入)可增加:

  • 计数器(防止重放)
  • 超时监控(命令必须在一定时间内完成)
  • 应用层 CRC(可选,用于高安全等级)

10.3 降级策略

当检测到严重错误(如 CAN 总线关闭、传感器故障)时,节点应自动进入安全状态,并持续发送错误状态帧。

11. 版本管理与扩展性

11.1 协议版本号

  • 主版本号变更:协议布局不兼容
  • 次版本号变更:新增字段且向后兼容(旧版本忽略未知字段)
  • 版本号置于通用头 proto_ver 字段

11.2 字段扩展

  • 每个载荷结构预留 2~8 字节保留字段
  • 新增字段应尽量放在载荷尾部,并更新 hdr_len(如头部变化)或使用保留字段

11.3 消息类型扩展

  • msg_type 使用 8 位,0x000x7F 用于上行,0x800xFF 用于下行(或相反)
  • 保留 0xF0~0xFF 为厂商自定义类型

12. 测试与验证要求

  1. 最小可行产品(MVP):先实现核心消息类型(如锚点、传感器数据、状态、Ping),验证物理层配置和基本通信。
  2. 总线负载测试:在最恶劣工况下计算理论负载率,实测确认无丢帧。
  3. 信号质量验证:使用示波器/逻辑分析仪检查数据段波形,确保上升沿、振铃在可接受范围。
  4. 兼容性测试:若与经典 CAN 节点共存,验证 CAN FD 节点在 BRS=0 时不会引起错误帧。
  5. 长期稳定性测试:连续运行 24 小时以上,检查丢包计数、错误标志是否正常。
  6. 分片与重组测试:模拟大数据块传输,验证超时重传、乱序重组功能。

13. 文档要求

协议设计应至少包含以下文档:

  • 协议规范:描述 ID 分配、帧格式、消息类型、载荷定义。
  • 实现指南:给出位时序计算示例、代码结构建议(如 proto.hcan_driver.c)。
  • 测试报告:记录测试环境、测试项、结果及问题。

14. 附录:典型协议结构示例(参考)

方向IDmsg_type载荷频率
上行0x1100x01锚点时间 + 源1 kHz
上行0x1110x02IMU 数据(32B)1 kHz
上行0x1120x03编码器数据(32B)200 Hz
上行0x1130x04系统状态(24B)10 Hz
下行0x1900x81控制命令(8B)异步
下行0x1910x82参数配置(16B)异步
下行0x19F0x8FPing 请求(4B)按需

本通用标准可作为任何 CAN FD 自定义协议设计的起点,实际应用时可根据具体需求裁剪或扩展。