首页 / CANopen专题

CAN FD 总线测试:周立功工具链、物理层眼图与协议一致性

经典 CAN 的测试方法(电平/终端电阻/错误帧,见CAN 总线测试篇)在 CAN FD 上继续适用,但 FD 多了四件必须单独验证的事:双波特率切换、双采样点、64 字节长帧、新的 CRC 与 ESI 机制——它们正是 FD 最容易出问题的地方。本文以周立功(ZLG)工具链为主线:USBCANFD 分析仪 + ZCANPRO 做数据链路层收发与错误统计,CANScope-Pro 做物理层眼图与一致性测试,讲清每个测试项怎么做、判据是什么,配 FD 帧解析与吞吐对比计算器交互演示和可编译 SocketCAN 测试代码。

1. CAN FD 测试的特殊性:四件"经典 CAN 没有"的事

CAN FD(ISO 11898-1:2015)与经典 CAN 的物理层完全兼容(都是差分双绞线、同样的电平规范),但协议层引入了四个新变量,每一个都会制造经典 CAN 时代不存在的故障形态:

新特性故障形态测试重点
双波特率(BRS)仲裁段/数据段切换点采样失败、BRS 位误判 → 整帧错位两段波特率与切换时序一致性(第 4 节)
双采样点两节点仲裁段采样点不一致、数据域采样点偏差 → 长帧尾部错位采样点实测(第 4 节)
64 字节长帧数据域持续 500 位以上高速传输,信号反射/振铃在长帧中段累计眼图、长帧误码(第 3、5 节)
CRC 17/21 + 固定填充 + ESI 位CRC 长度与填充规则错误、错误状态通过 ESI 传播帧结构逐位校验、错误注入(第 5 节)

测试策略与经典 CAN 相同的是框架(物理层 → 一致性 → 数据链路层 → 应用层,见07 篇),不同的是每个层次里都要为上述四个新变量增加专项测试项。

2. 测试工具链:周立功 USBCANFD + ZCANPRO + CANScope-Pro

周立功(致远电子 ZLG)的 CAN 测试工具分两级:分析仪做收发与协议观察,CANScope 做物理层深度测量与一致性测试。工业现场/研发实验室最常见的组合:

工具定位关键能力(CAN FD 相关)
USBCANFD-100U / 200UUSB-CAN FD 分析仪(1 路 / 2 路)CAN 波特率 40k~1Mbps、CAN FD 数据域 100k~5Mbps 任意可编程;支持 ISO 与 Bosch 两种 FD 标准;数据域最长 64 字节;USB 2.0 高速,单通道发送万帧/秒级;兼容 CAN 2.0A/B 模式
ZCANPRO上位机分析软件(配 USBCAN 系列)报文收发与统计、错误帧/总线负载实时显示;CAN FD 双波特率自定义(如 1Mbps(75%), 5Mbps(75%) 分别配采样点);DBC 解析与发送、报文记录回放;CANopen/J1939 协议解析
CANScope-ProCAN 总线综合分析仪(示波器+协议分析+误码率+压力测试一体)眼图(眼高/眼宽/抖动)、位时间与波特率实测、信号质量分析(幅值/斜率/扰动定位问题节点)、网络阻抗分析(60Ω±20%)、采样点测试、错误帧定位;配合 CANScope-StressZ 可做数字干扰注入、总线短路/长度/负载模拟等压力测试

典型测试拓扑:分析仪(USBCANFD 或 CANScope)作为独立节点挂上总线,不参与被测系统逻辑,只做观察/注入。总线两端各一只 120Ω 终端电阻(合计 60Ω),被测 DUT(驱动器/控制器)并联在中间。CANScope-StressZ 的压力测试模块可以在物理层上模拟短路、加长总线、增减负载、注入数字干扰,用来评估系统"在恶劣工况下是否仍稳定"。

✅ 测试接线三件事

① 分析仪 CAN_H/CAN_L 接总线对应线(别接反,显性电平会反);② 终端电阻:总线两端各 120Ω,实测 CAN_H-CAN_L 间约 60Ω(可先断电用万用表量);③ 共地:分析仪与被测系统地电位一致,避免共模偏差。

3. 物理层测试:眼图、位时间与信号质量(CANScope)

CAN FD 数据域跑到 2M~5M 时,位时间短到 500ns~200ns,信号完整性成为第一道关。CANScope 的实时示波器把大量波形按位周期叠加成眼图

测试项测量方法合格判据(参考)
眼图示波器自动量程,叠加足够波形后测眼高/眼宽眼高(差分幅度余量)充足、眼宽接近 1 个位时间;眼图"眼皮"越厚抖动越大
波特率实测测量位宽度(位宽 = 1/波特率),多测几个位取平均仲裁段/数据域实测波特率与配置偏差在容差内(125k 偏差案例:号称 125k 实测偏差超限 → 节点不同步)
信号质量按幅值/斜率/扰动特征逐节点评估波形快速定位"哪个节点波形差"(问题节点往往是反射源)
网络阻抗交流阻抗分析(5k~100kHz 频段)满足 60Ω ± 20%,超出说明终端电阻缺失/过多或支线异常
压力测试CANScope-StressZ 注入干扰、模拟短路/长度/负载系统在干扰/短路/高负载下仍不出现错误帧或可恢复

数据域 2M 以上时重点看数据段眼图:长帧后半段若出现眼宽收窄,往往是反射叠加(支线过长、终端不匹配);抖动集中在某个节点发出的帧上,优先查那个节点的收发器与 PCB 布线。物理层问题在协议层表现为"偶尔错误帧、偶发 bus-off",是最难排查的一类——所以测试顺序必须物理层先行。

4. 一致性测试:双波特率、双采样点与容差

CAN FD 一致性测试的核心是验证"DUT 的仲裁段/数据段波特率与采样点是否与设计一致"。原理与工具:CANScope 可以按指定波特率收 DUT 发出的帧,并测量 DUT 的实际采样点;ZCANPRO 侧则要把分析仪自身配成与被测网络完全一致的双波特率+双采样点,否则连"听"都听不到:

# ZCANPRO 自定义 CAN FD 波特率(仲裁 1M/75% + 数据 5M/75%,常见组合) # 仲裁域波特率选择"自定义",填入: 1.0Mbps(75%), 5.0Mbps(75%) # 括号内为采样点百分比;两段必须与 DUT 严格一致,否则收不到或乱帧

一致性测试的三个必做项:

  1. 双波特率验证:DUT 发 FD 帧(BRS=1),CANScope 分别实测仲裁段与数据段的实际波特率,偏差应在规范容差内(晶振容差 + SJW 吸收范围,见双波特率篇第 3 节)。
  2. 采样点实测:CANScope 的"采样点测试"功能——DUT 初始化后只监听不发,由 CANScope 主动发帧并扫描采样点,测出 DUT 真实采样点位置。经典 CAN 时代不少项目采样点偏差 5% 内"能用就行",FD 数据域位时间只有几百 ns,5% 就是几十 ns,长帧必错。
  3. 切换点一致性:BRS 位后的第一个数据域位、CRC 定界符前的最后一个数据域位,采样时刻必须与两段各自的波特率相位对齐;切换点附近出现毛刺/错位,直接抓 FD 帧时序图看。
⚠️ 最常见的"听不到"原因

分析仪只配了仲裁波特率、没配数据域波特率,或两段采样点与 DUT 不一致——ZCANPRO 会一直"收不到帧"或帧内容乱码。先核对双波特率+双采样点四项配置,再怀疑硬件。

5. 协议层测试:FD 帧结构、错误注入与 ESI 位

数据链路层的测试对象是"帧对不对、错怎么报"。CAN FD 帧结构与经典 CAN 的差异(详细位序见05 篇)在测试时要逐位验证:

字段FD 帧(BRS=1)测试验证点
FDF1 = FD 帧经典节点看到 FDF=1 会报格式错误——混跑网段要测"经典节点是否被 FD 帧干扰"
BRS1 = 数据域提速切换点位置正确;BRS=0 的"全速帧"与 BRS=1 帧都要能收
ESI0 = 发送方错误主动;1 = 错误被动FD 新增:接收方可直接看到发送节点的错误状态——测"DUT 进入错误被动后发出的帧 ESI=1"
DLC0~15(编码 0~8/12/16/20/24/32/48/64)64 字节长帧收发正确;非 8/16/32/64 的中间长度也按规范编码
CRCDLC≤16 用 CRC17(+5 固定填充位);DLC>16 用 CRC21(+6 固定填充位)CRC 字段长度固定(22/27 位),数据段本身不填充——CRC 错判为填充错误是 FD 特有的错误注入点

错误注入测试是协议层测试的核心手段:用分析仪人为制造单点错误,验证 DUT 的错误检测与状态机响应(错误帧五类与错误状态机见07 篇第 4 节,FD 上同样适用):

  1. 位错误注入:发送时在固定位位置翻转一位,DUT 应检出并回错误帧;
  2. 填充错误注入:在数据段制造 6 个连续相同位(FD 数据段无填充,连续 6 位即违规)——这是 FD 特有的注入点,经典 CAN 测试不会覆盖;
  3. CRC 错误注入:改写 CRC 字段,DUT 应报 CRC 错误;
  4. ACK 缺失:分析仪"只听不答"模式(不产生 ACK),观察 DUT 的发送错误计数与错误状态迁移。

注入后观察两个指标:错误帧统计(ZCANPRO 的统计面板实时显示各类错误帧数量)与错误状态迁移(错误主动 ↔ 错误被动 ↔ bus-off,配合 ESI 位验证——DUT 错误被动后发出的 FD 帧 ESI 位应为 1,这能确认 ESI 机制真正生效)。

6. 负载与吞吐:CAN FD 值不值,用数据说话

引入 FD 的核心收益是吞吐。测试时用分析仪统计总线负载率(bus load)并在同一条总线上对比"经典 8 字节帧"与"FD 64 字节帧"的实际效果。理论值可精确计算(见第 7 节演示):

同一数据量 64 字节:经典 vs FD(仲裁 500k / 数据 2M)

经典 CAN:8 帧 × 8 字节 ≈ 8 × 256µs ≈ 2.05ms(单帧约 128 位含填充)

CAN FD:1 帧 × 64 字节 ≈ 340µs(仲裁段 44µs + 数据域 270µs + 尾部 26µs)

→ 同样数据量,总线占用时间降为约 1/6,有效吞吐提升约 6 倍

实测注意:负载率按位时间占比统计(FD 帧里数据域位更快,占用总线时间更短),所以 ZCANPRO/CANScope 统计 FD 负载率时会按各段实际波特率加权——不要用"帧数 × 单帧长度"毛估。

7. 交互式演示:CAN FD 帧解析与吞吐对比计算器

输入仲裁/数据波特率、DLC 与 BRS 开关,实时计算单帧总时长、最大帧率、有效吞吐,并与经典 CAN(同仲裁波特率、8 字节帧)对比。所有数值按位长度与波特率真实计算,可对照第 6 节公式复核。

CAN FD 帧解析与吞吐对比计算器
仲裁 500k / 数据 2M / 64B:帧 339.5µs · 最大帧率 2946 帧/s · 有效吞吐 1.51 Mbps · 对比经典 CAN(8 帧)提升 ≈ 6.0 倍。

观察要点:数据域提速越狠、DLC 越大,吞吐倍数越可观;DLC≤16 时用 CRC17(22 位)、DLC>16 用 CRC21(27 位),切换点正好在 16 字节处;BRS 关闭时整帧走仲裁波特率(相当于"FD 格式但单速率"),吞吐明显回落——这正是短帧场景"FD 未必更快"的原因。

8. 可编译测试代码:SocketCAN FD 收发与错误统计

Linux 侧用 SocketCAN 即可完成大部分协议层测试:发 FD 帧(可带 BRS)、收帧、统计错误帧。下面是完整可编译的测试程序:

/* canfd_test.c —— Linux SocketCAN CAN FD 收发与错误帧统计 * 编译:gcc -o canfd_test canfd_test.c * 运行:sudo ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on * sudo ip link set can0 up * sudo ./canfd_test can0 0x123 64 * 说明:向 can0 连续发送 1000 帧 CAN FD(BRS 加速),同时统计回环接收与错误帧 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <linux/can.h> #include <linux/can/raw.h> int main(int argc, char **argv) { const char *ifname = argc > 1 ? argv[1] : "can0"; uint32_t id = argc > 2 ? (uint32_t)strtoul(argv[2], NULL, 0) : 0x123; unsigned int dlen = argc > 3 ? (unsigned int)strtoul(argv[3], NULL, 0) : 64; if (dlen > 64) dlen = 64; int s = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (s < 0) { perror("socket"); return 1; } struct ifreq ifr; strcpy(ifr.ifr_name, ifname); if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl"); return 1; } struct sockaddr_can addr; memset(&addr, 0, sizeof(addr)); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } /* 开启错误帧接收(默认被过滤,必须显式设置) */ can_err_mask_t err_mask = CAN_ERR_MASK; setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask)); /* 发送 FD 帧:BRS=1 数据域加速 */ struct canfd_frame tx; memset(&tx, 0, sizeof(tx)); tx.can_id = id; tx.len = dlen; tx.flags = CANFD_BRS; for (unsigned int i = 0; i < dlen; i++) tx.data[i] = (unsigned char)i; /* 接收超时 200ms,用于退出接收循环 */ struct timeval tv = { 0, 200000 }; setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); unsigned long sent = 0, recv = 0, err_frames = 0; for (int i = 0; i < 1000; i++) { if (write(s, &tx, sizeof(tx)) != sizeof(tx)) { perror("write"); break; } sent++; while (1) { struct canfd_frame rx; ssize_t n = read(s, &rx, sizeof(rx)); if (n < 0) break; /* 超时退出 */ if (rx.can_id & CAN_ERR_FLAG) { /* 错误帧 */ err_frames++; printf("ERR frame: can_id=0x%08x\n", rx.can_id); continue; } recv++; break; /* 只统计本帧回环 */ } } printf("sent=%lu recv=%lu err_frames=%lu\n", sent, recv, err_frames); close(s); return 0; }

Windows 侧用周立功 SDK(VCI 接口)做同样的事:ZCAN_OpenDevice 打开 USBCANFD → ZCAN_InitCAN 配置双波特率+双采样点 → ZCAN_StartCAN → 用 VCI_CANFD_FRAME 结构(含 flags 的 FDF/BRS/ESI 位、data[64])收发。字段位定义以 ZLG SDK 头文件(zcan.h)为准,工程上直接看 SDK 示例工程的 canfd_loopback 例程即可。

9. CAN FD 测试清单(Checklist)

层次测试项判据/工具通过
物理层终端电阻万用表 CAN_H-CAN_L ≈ 60Ω
眼图(眼高/眼宽/抖动)CANScope-Pro;数据段 2M+ 重点看
波特率实测位宽 = 1/波特率,两段分别测
网络阻抗 / 压力测试60Ω±20%;StressZ 短路/干扰注入
一致性双波特率配置一致性分析仪与 DUT 仲裁/数据段完全一致
双采样点实测CANScope 采样点测试;与设计值偏差在容差内
BRS 切换点FD 帧时序图,两段相位对齐
数据链路FD 帧结构逐位验证FDF/BRS/ESI/DLC/CRC17↔21 边界(16B)
64 字节长帧双向收发 1000 帧无错
错误注入位/填充/CRC/ACK 错误 → 错误帧正确上报
ESI 位与错误状态错误被动节点发出的帧 ESI=1
应用层负载率与吞吐对比FD 64B vs 经典 8 帧,实测符合理论
长时间稳定性满载 8h 无错误帧、无 bus-off

10. 工程要点

11. 小结

  1. CAN FD 测试 = 经典 CAN 测试框架 + 四个专项:双波特率、双采样点、64 字节长帧、CRC/ESI 机制
  2. 工具链:USBCANFD + ZCANPRO 做数据链路层收发与错误统计;CANScope-Pro 做物理层眼图与一致性测试
  3. 物理层:眼图/位时间/网络阻抗 60Ω±20%/压力测试,数据域 2M+ 必测
  4. 一致性:双波特率双采样点逐位对齐,采样点用 CANScope 实测而非只看配置
  5. 数据链路:FD 帧结构逐位验证 + 四类错误注入 + ESI 位验证错误状态传播
  6. 吞吐用数据说话:FD 64B 帧理论约 5 倍于经典 8 帧(500k/2M 组合),实测以总线负载统计为准

CAN 板块链路至此补齐:帧与 SocketCAN(04)→ 双波特率采样点(05)→ 伺服实战(06)→ 经典 CAN 测试(07)→ Modbus 寄存器(08)→ CAN FD 测试(本篇)。