linux cansend candump 命令介绍和使用示例
在 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模块: bashsudo modprobe vcan -
添加
vcan0接口: bashsudo ip link add dev vcan0 type vcan -
启用
vcan0接口: bashsudo ip link set up vcan0现在,你可以使用
ip link show vcan0或ifconfig(如果已安装) 来查看vcan0接口是否已成功创建并处于UP状态。
candump 基本用法
candump 用于监听和显示 CAN 总线上的报文。它就像网络中的 tcpdump 工具一样,可以捕获指定 CAN 接口上的所有或过滤后的 CAN 帧。
打开一个终端窗口,运行 candump 来监听 vcan0 接口上的所有 CAN 报文:
candump vcan0此时,终端会等待并显示任何在 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增加颜色级别。- 示例:
candump -cc vcan0
- 示例:
-
-D: 即使 CAN 设备下线也不退出。 -
-e: 以人类可读格式显示 CAN 错误帧。 -
过滤报文: 你可以指定只捕获特定 CAN ID 或 ID 范围的报文。格式是
<can_id>:<can_mask>。只有当(received_can_id & mask) == (can_id & mask)时,报文才会被显示。-
示例 (只显示 ID 为
123的报文): bashcandump vcan0,123:7FF7FF是标准 CAN ID 的掩码,确保只匹配 ID123。 -
示例 (只显示 ID 范围在
200到2FF之间的报文): bashcandump vcan0,200:7F0这里
7F0意味着只关注CAN ID的高 7 位,低 4 位不限制。 -
示例 (扩展 ID 过滤):
bashcandump vcan0,12345678:DFFFFFFFDFFFFFFF是扩展 CAN ID 的掩码。
-
cansend 基本用法
cansend 用于向 CAN 总线发送单个 CAN 报文。
打开另一个终端窗口,运行 cansend 向 vcan0 发送报文。
发送标准 CAN 2.0 数据帧 (11 位 ID):
cansend vcan0 123#1122334455667788vcan0: 要发送报文的 CAN 接口。123: CAN ID (十六进制,这里是 11 位标准 ID)。#: 分隔符,表示后面是数据。1122334455667788: 数据段(十六进制),最大 8 个字节。
如果你在第一个终端运行着 candump vcan0,你应该能看到这条报文被成功捕获并显示出来。
常用格式
cansend 支持多种报文格式:
-
经典 CAN 2.0 数据帧:
<can_id>#{data}: 发送数据帧。- 示例 (空数据帧):
cansend vcan0 100# - 示例 (2 字节数据):
cansend vcan0 200#AA.BB(数据字节可以用.分隔,也可以不分隔) - 示例 (3 字节数据):
cansend vcan0 300#010203
- 示例 (空数据帧):
-
CAN FD 数据帧 (CAN Flexible Data Rate):
<can_id>##<flags>{data}: 发送 CAN FD 帧。<flags>: 单个十六进制值 (0-F),定义canfd_frame.flags。- 示例 (CAN FD,ID
500,标志1,64 字节数据):(注意,这里的数据长度超过了经典 CAN 的 8 字节限制) bashcansend vcan0 500##10102030405060708090A0B0C0D0E0F0102030405060708090A0B0C0D0E0F0102030405060708090A0B0C0D0E0F0102030405060708090A0B0C0D0E0F
-
远程请求帧 (RTR, Remote Transmission Request):
<can_id>#R: 发送一个 RTR 帧,请求对应 ID 的数据。- 示例:
cansend vcan0 123#R
- 示例:
<can_id>#R{len}: 带 DLC 的 RTR 帧。- 示例:
cansend vcan0 123#R8(请求 8 字节数据)
- 示例:
-
扩展 CAN ID (29 位 ID):
- CAN ID 可以是 3 (SFF, Standard Frame Format) 或 8 (EFF, Extended Frame Format) 个十六进制字符。如果 CAN ID 是 8 位十六进制数,它会自动被识别为扩展 ID。
- 示例 (扩展 ID
18FEF100,数据010203): bashcansend vcan0 18FEF100#010203
总结
cansend 和 candump 是 Linux SocketCAN 工具集中最基础也是最常用的两个命令。它们是进行 CAN 总线开发、调试和测试的利器。通过这些命令,你可以:
- 发送特定 CAN 报文来模拟设备行为或触发特定功能。
- 监听和分析 CAN 总线流量,以理解设备间的通信模式,诊断问题。
- 记录 CAN 报文到文件,以便后续分析或回放。
熟练掌握这两个命令对于任何进行 Linux 下 CAN 开发的工程师都至关重要。