CAN调试 使用方式与典型场景
四、使用方式与典型场景
下面给出几个可直接使用的调试流程与脚本。
示例一,完整的总线抓包与离线分析流程。把抓包、记录、统计串起来,是现场排查的标准动作:
# 配置接口
sudo ip link set can0 up type can bitrate 500000 sample-point 0.875
# 记录到文件(带时间戳,可 Ctrl+C 停止)
candump -l can0
# 生成的文件形如 candump-2026-01-01_120000.log
# 只看某几个 ID
candump can0,100:7FF,200:7FF
# 统计总线负载,每 2 秒刷新
canbusload can0@500000 -t -r
# 回放记录文件,按原始时间间隔
canplayer -I candump-2026-01-01_120000.log
# 观察哪些字节在变化
cansniffer -c can0
示例二,用 Python 做一条自动化测试脚本,验证某个控制报文是否按预期周期与预期值发出。这类脚本适合放进回归测试,换型或固件升级后跑一遍:
import can, time
TARGET_ID = 0x201
EXPECT_PERIOD_MS = 20.0
TOLERANCE_MS = 3.0
bus = can.interface.Bus(channel="can0", bustype="socketcan")
last = None
count = 0
bad = 0
start = time.time()
while time.time() - start < 10:
frame = bus.recv(timeout=1.0)
if frame is None or frame.arbitration_id != TARGET_ID:
continue
now = time.time()
if last is not None:
dt = (now - last) * 1000
count += 1
if abs(dt - EXPECT_PERIOD_MS) > TOLERANCE_MS:
bad += 1
print("周期超差: %.1f ms" % dt)
last = now
print("样本 %d,超差 %d,超差率 %.1f%%" % (count, bad, 100.0 * bad / max(count, 1)))
示例三,定位 Bus-Off 的排查顺序。节点进入 Bus-Off 意味着它的发送错误计数超过了协议规定的上限,通常按这个顺序查:先测总线电阻是否为约 60 欧姆;再确认该节点的波特率与采样点是否与其他节点一致;再确认总线上至少有另一个正常工作且会应答的节点;最后检查该节点的收发器供电与地线。如果单节点测试时一切正常、一挂上整机就出问题,重点怀疑波特率与采样点,以及是否有个别节点的收发器性能异常拉低了整个总线的信号质量。
适用与不适用场景对照。
| 场景 | 是否合适 | 说明 |
|---|---|---|
| 机器人关节、电机驱动器的控制总线 | 非常合适 | CAN 的经典应用,实时性与可靠性兼顾 |
| 电池管理系统与整车通信 | 非常合适 | 抗干扰强,线束成本低 |
| 强电磁干扰的工业现场 | 合适 | 差分传输抗共模干扰,注意屏蔽与共地 |
| 需要传输大量数据(图像、文件) | 不合适 | 经典 CAN 每帧最多 8 字节,带宽不足 |
| 高刷新率多轴同步控制 | 需评估 | 节点数与周期数多时总线负载会饱和,考虑 EtherCAT |
| 超长距离(数百米以上) | 受限于波特率 | 速率越高可用距离越短,需按标准降速 |
| 只有两个节点且不需广播 | 可能过度设计 | 简单点对点场景用串口更省成本 |
