在 Linux 系统中,cansend 和 candump 是 can-utils 工具包中两个非常重要的命令行工具,用于进行 CAN (Controller Area Network) 总线通信的发送和接收。这些工具基于 Linux 内核的 SocketCAN 接口,使得 CAN 总线操作就像操作网络接口一样方便。
前提
在使用这些工具之前,你需要确保你的 Linux 系统支持 SocketCAN,并且 CAN 接口(无论是物理接口如 USB-CAN 适配器,还是虚拟接口如 vcan)已经正确配置和启用。
准备 CAN 接口 (以虚拟 CAN 接口 vcan0 为例)
为了演示 cansend 和 candump,我们通常会使用一个虚拟 CAN 接口 (vcan)。这不需要实际的 CAN 硬件,非常适合学习和测试。
-
加载 vcan 模块:
-
添加 vcan0 接口:
sudo ip link add dev vcan0 type vcan
-
启用 vcan0 接口:
sudo ip link set up vcan0
现在,你可以使用 ip link show vcan0 或 ifconfig (如果已安装) 来查看 vcan0 接口是否已成功创建并处于UP状态。
candump 基本用法
candump 用于监听和显示 CAN 总线上的报文。它就像网络中的 tcpdump 工具一样,可以捕获指定 CAN 接口上的所有或过滤后的 CAN 帧。
打开一个终端窗口,运行 candump 来监听 vcan0 接口上的所有 CAN 报文:
此时,终端会等待并显示任何在 vcan0 上接收到的 CAN 报文。
candump 输出格式
典型的 candump 输出格式如下:
(1705641777.123456) can0 123 [8] 11 22 33 44 55 66 77 88
(1705641777.123456): 时间戳,表示接收到报文时的系统时间(秒.微秒)。
can0: 接收到报文的 CAN 接口名称。
123: CAN ID(十六进制),这里是标准 CAN ID (11 位)。如果是扩展 CAN ID (29 位),则会显示 8 位十六进制数,例如 12345678。
[8]: 数据长度码 (DLC, Data Length Code),表示数据段的字节数,这里是 8 字节。
11 22 33 44 55 66 77 88: CAN 报文的数据段(十六进制表示)。
常用选项
-
-t <type>: 时间戳格式。
a: 绝对时间戳 (Absolute timestamp)。
d: 相对时间戳 (Delta timestamp),显示与上一条报文的时间差。
z: 零点时间戳 (Zero timestamp),以 candump 启动时为零点。
A: 带日期的绝对时间戳 (Absolute timestamp with date)。
- 示例:
candump -tA vcan0
-
-l: 将报文记录到文件。默认文件名是 candump-<interface>.log。
- 示例:
candump -l vcan0
这将把捕获到的报文保存到 candump-vcan0.log 文件中。
-
-s <level>: 静默模式,不显示数据帧,只显示错误帧。
candump -s 2 vcan0 (默认等级 2)
-
-c: 彩色输出,使得不同报文在终端中以不同颜色显示,方便区分。可以多次使用 -c 增加颜色级别。
-
-D: 即使 CAN 设备下线也不退出。
-
-e: 以人类可读格式显示 CAN 错误帧。
-
过滤报文: 你可以指定只捕获特定 CAN ID 或 ID 范围的报文。格式是 <can_id>:<can_mask>。只有当 (received_can_id & mask) == (can_id & mask) 时,报文才会被显示。
-
示例 (只显示 ID 为 123 的报文):
7FF 是标准 CAN ID 的掩码,确保只匹配 ID 123。
-
示例 (只显示 ID 范围在 200 到 2FF 之间的报文):
这里 7F0 意味着只关注 CAN ID 的高 7 位,低 4 位不限制。
-
示例 (扩展 ID 过滤):
candump vcan0,12345678:DFFFFFFF
DFFFFFFF 是扩展 CAN ID 的掩码。
cansend 基本用法
cansend 用于向 CAN 总线发送单个 CAN 报文。
打开另一个终端窗口,运行 cansend 向 vcan0 发送报文。
发送标准 CAN 2.0 数据帧 (11 位 ID):
cansend vcan0 123#1122334455667788
vcan0: 要发送报文的 CAN 接口。
123: CAN ID (十六进制,这里是 11 位标准 ID)。
#: 分隔符,表示后面是数据。
1122334455667788: 数据段(十六进制),最大 8 个字节。
如果你在第一个终端运行着 candump vcan0,你应该能看到这条报文被成功捕获并显示出来。
常用格式
cansend 支持多种报文格式:
总结
cansend 和 candump 是 Linux SocketCAN 工具集中最基础也是最常用的两个命令。它们是进行 CAN 总线开发、调试和测试的利器。通过这些命令,你可以:
- 发送特定 CAN 报文来模拟设备行为或触发特定功能。
- 监听和分析 CAN 总线流量,以理解设备间的通信模式,诊断问题。
- 记录 CAN 报文到文件,以便后续分析或回放。
熟练掌握这两个命令对于任何进行 Linux 下 CAN 开发的工程师都至关重要。