CAN 和 CANFD

一、引言

CAN(Controller Area Network)总线自 1986 年由 Bosch 公司推出以来,已成为车载网络的事实标准。但随着现代汽车电子系统的日益复杂,经典 CAN 的局限性逐渐凸显------单帧 8 字节、最高 1 Mbps 的带宽已无法满足域控制器、自动驾驶等场景下的大数据传输需求。2012 年发布的 CAN FD(CAN with Flexible Data rate) 在保持经典 CAN 最大兼容性的同时,突破了这两大瓶颈。


二、核心区别一览

维度 经典 CAN (CAN 2.0A/B) CAN FD
单帧最大数据长度 8 字节 64 字节
速率 全程单一速率,最高 1 Mbps 仲裁段 ≤ 1 Mbps(同 CAN),数据段最高 5~8 Mbps
帧结构 全程同一速率 仲裁段 → 速率切换 → 数据段
CRC 校验 15-bit CRC 17-bit CRC,误检率更低
兼容性 --- CAN FD 控制器能收 经典 CAN;经典 CAN 收不了 CAN FD 帧
收发器 经典 CAN 收发器 必须用 CAN FD 收发器(如 TJA1463)
总线长度 500 kbps 下约 40 米 数据段高速下约 10 米以内

三、数据帧结构差异

经典 CAN 和 CAN FD 的仲裁段(ID 竞争阶段)完全相同 ,速率也一样。CAN FD 在仲裁结束后,发送方通过一个 FDF(FD Format)位 通知接收方:"接下来要切到高速模式了"。

复制代码
经典 CAN 帧:
┌─────────┬──────┬──────────┬──────┐
│ 仲裁段  │ 数据 │ CRC/ACK  │ 结束 │
│ ≤1Mbps  │ ≤8B  │  15-bit  │      │
└─────────┴──────┴──────────┴──────┘

CAN FD 帧:
┌─────────┬──────┬──────────┬──────┐
│ 仲裁段  │ 数据 │ CRC/ACK  │ 结束 │
│ ≤1Mbps  │ ≤64B │  17-bit  │      │
└─────────┴──────┴──────────┴──────┘
              ▲
              │ 这里插入 FDF 位 + BRS 位,
              │ 通知硬件切换数据段波特率

这意味着 CAN FD 帧对经典 CAN 控制器来说,仲裁段能看懂,但一旦读到 FDF 位就会把整帧当作"未知格式"丢弃------这是硬件层面的不兼容,无法通过软件解决。


四、为什么需要 CAN FD

经典 CAN 的 8 字节 + 1 Mbps 在现代车上面临三大压力:

4.1 域控制器架构下的数据瓶颈

传统分布式架构中一个 ECU 只负责一个功能(比如变速箱 ECU、刹车 ECU),CAN 总线能撑住。但域控制器把十几个 ECU 整合成一个大脑,需要传输的数据量呈数量级增长------固件升级、诊断日志、摄像头预览等场景下,经典 CAN 一帧只能带 8 字节,光升级一个 2MB 的固件就要发几十万帧。

4.2 自动驾驶的传感器数据传输

激光雷达、摄像头的原始数据如果走 CAN,经典 CAN 根本扛不住。CAN FD 的 64 字节帧 + 5 Mbps 数据段,吞吐量提升了约 6~8 倍。

4.3 车内网络成本

CAN FD 可以用更少的总线、更低的成本满足更高带宽需求,在车载以太网普及之前是最务实的过渡方案。


五、在 DBC 文件中的体现

5.1 波特率段 BS_

这是最直接、最标准的判断依据。

经典 CAN:

复制代码
BS_: 500000

CAN FD:

复制代码
BS_: 500000, 2000000

逗号分隔两个数值:仲裁段波特率在前,数据段波特率在后。

5.2 Signal 长度上限

经典 CAN 单帧 8 字节 → Signal 长度最大 64 bit 。 CAN FD 单帧 64 字节 → Signal 长度最大 512 bit。

DBC 中 SG_ 段的 Length 字段超过 64,必然是 CAN FD。

5.3 其他标记

部分 DBC 工具会通过注释或自定义 BA_DEF_ 属性标记总线类型:

复制代码
BA_DEF_  "BusType" STRING ;
BA_DEF_DEF_  "BusType" "CANFD";

但这不是标准字段,不可靠。BS_ 段的双波特率是唯一可靠的判断方式。


六、编程层面的影响

6.1 车型 Protocol 类(应用层)

变化极小,核心就是数据长度从 ≤8 变成 ≤64。

一个 Protocol 类典型的三个关键点:

复制代码
// 1. 帧 ID ------ 和 CAN/CAN FD 无关,取决于车型 CAN 矩阵
const int32_t Accelcmd100::ID = 0x100;

// 2. 帧长度 ------ 经典 CAN ≤ 8,CAN FD 可以 ≤ 64
int32_t Accelcmd100::GetLength() const { return 8; }

// 3. 位定义、缩放因子、物理量转换 ------ 与 CAN/CAN FD 无关,照搬 DBC
void Accelcmd100::set_p_accel_cmd(uint8_t* data, double accel_cmd) {
  uint16_t raw = static_cast<uint16_t>(accel_cmd / 0.001);  // 精度 0.001
  data[1] = (raw >> 8) & 0xFF;
  data[2] = raw & 0xFF;
}

对应用层开发者来说:适配一辆 CAN FD 车型,Protocol 类代码逻辑和经典 CAN 完全一样,只是 GetLength() 返回值变大了。

6.2 底层驱动(CAN Client)

变化较大,需要处理:

  1. CanFrame 结构体 ------ data[8] 需要扩成 data[64],len 字段语义变化

  2. FD 帧标志位 ------ 需要一个字段告诉硬件"这是 CAN FD 帧"

  3. 双波特率配置 ------ 仲裁段波特率和数据段波特率分开设置

  4. 收发器配置 ------ 必须切换到 CAN FD 模式

    Apollo当前CanFrame定义为经典CAN设计:

    复制代码
    struct CanFrame {
      uint32_t id;
      uint8_t data[8];  // ← 仅支持8字节,CAN FD需扩展至64字节
      uint8_t len;
    };

    需修改为:

    复制代码
    struct CanFrame {
      uint32_t id;
      uint8_t data[64];  // 支持CAN FD帧
      uint8_t len;       // 帧长度,经典CAN≤8,CAN FD≤64
      bool is_fd_frame;  // ← 新增:标记是否为CAN FD帧
    };
    双波特率配置

    CAN FD需分别设置仲裁段和数据段波特率,而非经典CAN的单一配置:

    复制代码
    // 经典CAN驱动初始化
    can_client_->Init(500000);
    // CAN FD驱动初始化
    can_client_->Init(500000, 2000000);  // 仲裁段500k,数据段2M

6.3 硬件层

  • CAN 卡(如 PEAK PCAN、Vector VN1640)必须支持 CAN FD

  • 收发器必须是 CAN FD 型号(经典 CAN 收发器硬件上不识别 FDF 位)

  • 总线长度要控制在数据段高速模式允许的范围内

  • CAN总线首尾两个节点 必须各加一个120Ω终端电阻 ,中间节点绝对不能加------这是CAN总线能可靠通信的硬性要求。原理:消除高速信号反射


七、兼容性矩阵

发送端 接收端 经典 CAN 帧 CAN FD 帧
经典 CAN 控制器 经典 CAN 控制器 ✅ ❌
CAN FD 控制器 经典 CAN 控制器 ✅ ❌
CAN FD 控制器 CAN FD 控制器 ✅ ✅

CAN FD 控制器向下兼容经典 CAN,但经典 CAN 无法理解 CAN FD------这意味着车载网络中只要还有一个经典 CAN 节点,就不能在那条总线上发 CAN FD 帧。车厂的应对策略通常是:在域控制器内部的高速通道用 CAN FD,对外保留经典 CAN 总线与传统 ECU 通信。


八、总结

角度 一句话
协议本身 CAN FD = 更大的帧(64B)+ 更快的数据段(5~8 Mbps)+ 更强的 CRC
DBC 识别 BS_ 段有两个波特率即 CAN FD
应用层开发 和经典 CAN 几乎一样,只是数据长了
底层驱动 需要扩展 CanFrame、加 FD 标志、双波特率
硬件 必须换 CAN FD 收发器
兼容性 CAN FD 能收经典 CAN,经典 CAN 不能收 CAN FD

CAN FD 不是 CAN 的替代品,而是经典 CAN 的向后兼容的扩展------它在不破坏现有车载网络架构的前提下,为车厂提供了向域控制器、自动驾驶等高带宽场景平滑过渡的路径。

相关推荐
飞猫的边缘AI1 天前
车载相机产业链的竞争格局
自动驾驶·边缘ai
地平线开发者1 天前
地平线征程6M YOLOv8s 部署
算法·自动驾驶
星创易联1 天前
无人驾驶通信方案解析:Robotaxi、Robobus与无人矿卡如何选择车载网关?
车载系统·机器人·自动驾驶·信息与通信·无人矿卡
地平线开发者3 天前
MQBench QAT量化实践指南
人工智能·算法·自动驾驶
飞猫的边缘AI4 天前
边缘AI在自动驾驶应用中的行话汇总
人工智能·自动驾驶·芯片·模型·边缘ai·ai场景·城市noa
飞猫的边缘AI4 天前
边缘AI为什么加速上车了?
人工智能·自动驾驶·辅助驾驶·vla·noa·边缘ai·ai场景
小黄蚁4 天前
无人驾驶入门笔记(一)
笔记·自动驾驶·信息与通信
7yewh7 天前
SLAM 从视觉里程计到建图(6)
数据结构·人工智能·机器人·自动驾驶·嵌入式
强壮的CAT8 天前
VINS-Fusion 移植 ROS2 Jazzy 踩坑(一):环境与编译
人工智能·算法·机器人·自动驾驶