Can-Utils 工具集详解
目录
can-utils 是 Linux 上最常用的 CAN 调试工具集,包含多个实用工具,几乎涵盖所有基础 CAN 调试需求。
1. can-utils 安装
1.1 Ubuntu/Debian
sudo apt-get update
sudo apt-get install can-utils1.2 从源码编译(推荐获取最新版本)
git clone https://github.com/linux-can/can-utils.git
cd can-utils
./autogen.sh
./configure
make
sudo make install1.3 验证安装
# 查看所有可用工具
candump --help
cansend --help
canplayer --help2. 核心工具详解
2.1 candump - CAN 帧捕获工具
candump 是最常用的工具,用于捕获和显示 CAN 总线上的所有帧。
基本用法
# 捕获 vcan0 上的所有帧
candump vcan0
# 输出示例:
vcan0 123#DEADBEEF # 标准帧,ID=0x123,数据=0xDEADBEEF
vcan0 123#DEADBEEF # 时间戳格式
vcan0 180#01.00.00.00.00.00.00.00 # 扩展帧
vcan0 200#8 byte data with spaces高级过滤
# 只捕获特定 ID 的帧
candump vcan0,123:7ff # 掩码 0x7ff 只匹配低 11 位
# 捕获 ID 范围
candump vcan0,100:780 # 匹配 0x100-0x17F
# 捕获多个 ID
candump vcan0,123:7ff vcan0,456:7ff
# 使用过滤器文件
cat > filter.txt << 'EOF'
vcan0,580:7ff
vcan0,600:7ff
vcan0,700:7ff
EOF
candump -F filter.txt vcan0日志记录
# 记录到文件
candump -l vcan0
# 指定日志文件名
candump -l -L can_log_ vcan0 # 生成 can_log_<timestamp>.log
# 同时显示和记录
candump -l -d vcan0
# 日志文件格式示例 (cat can_log_20240520_143022.log)
(000.000000) vcan0 580#01100580
(000.000501) vcan0 580#01100580
(000.001002) vcan0 600#01时间戳选项
# 使用硬件时间戳(如果支持)
candump -H vcan0
# 使用相对时间戳
candump -t vcan0 # 默认
# 使用绝对时间戳
candump -T vcan0
# 使用 ISO 8601 时间戳
candump -tz vcan02.2 cansend - CAN 帧发送工具
用于向 CAN 总线发送单帧数据。
基本用法
# 发送标准帧
cansend vcan0 123#DEADBEEF
# 发送扩展帧
cansend vcan0 123#DEADBEEF
# 发送 8 字节数据
cansend vcan0 123#0102030405060708
# 发送较少字节数据(自动填充 00)
cansend vcan0 123#11 # 只发送 1 字节CANopen 示例发送
# NMT 命令:启动节点 2
# 功能码=0x000, 节点ID=0x002, 命令=0x01 (Start Remote Node)
cansend vcan0 000#0102
# 心跳报文(节点 1,状态=5 Operational)
# 功能码=0x700, 节点ID=0x001
cansend vcan0 701#05
# SDO 读取请求(从节点 2 读取 0x1000:00)
# 功能码=0x600, 节点ID=0x002
# CCS=0x40 (Initiate Upload), Index=0x1000, SubIndex=0x00
cansend vcan0 602#40100000
# SDO 写入请求(向节点 2 的 0x1000:01 写入 0x12345678)
# CCS=0x23 (Initiate Download), Index=0x1000, SubIndex=0x01
# Data=0x12345678 (4字节 Expedited)
cansend vcan0 602#2310000112345678批量发送(Shell 脚本)
#!/bin/bash
# send_nmt_start.sh - 启动所有节点
INTERFACE="vcan0"
MAX_NODES=10
for i in $(seq 1 $MAX_NODES); do
printf "Starting node %d\n" $i
cansend $INTERFACE 000#01$(printf "%02X" $i)
sleep 0.1
done
# 发送心跳
for i in $(seq 1 $MAX_NODES); do
cansend $INTERFACE $(printf "7%02X" $i)#05
done2.3 cangen - CAN 帧生成工具
用于持续生成 CAN 帧,常用于压力测试或模拟设备。
基本用法
# 生成随机帧,默认 100 帧/秒
cangen vcan0
# 指定 ID 和数据模式
cangen -v vcan0 -g 100 -D 1122334455667788 -I 123
# 参数说明:
# -v: 详细模式
# -g 100: 100 帧/秒
# -D: 固定数据
# -I: 固定 ID数据模式选项
# 使用递增数据
cangen vcan0 -L i # increment
# 使用递减数据
cangen vcan0 -L d # decrement
# 使用随机数据
cangen vcan0 -L r # random(默认)
# 使用自定义模式
cangen vcan0 -m 1122334455667788 # 模式数据ID 生成选项
# 固定 ID
cangen vcan0 -I 123
# 随机 ID(11-bit 范围)
cangen vcan0 -i
# 扩展帧 ID
cangen vcan0 -I 12345678 -e
# ID 递增
cangen vcan0 -L i -I 100CANopen 模拟示例
# 模拟节点 1 的 PDO 发送(RPDO 0x200)
cangen vcan0 -I 200 -e -g 10 -v -D "11 22 33 44 55 66 77 88"
# 模拟心跳报文
while true; do
cansend vcan0 701#05
sleep 1
done
# 模拟节点 2 的 NMT 状态变化
for state in 0 4 5; do # Initial -> Pre-Operational -> Operational
cansend vcan0 702#$state
sleep 1
done2.4 canplayer - CAN 帧回放工具
用于回放之前记录的 CAN 日志,适用于复现问题或测试。
基本用法
# 回放日志文件(保持原始时间间隔)
canplayer -I can_log.log vcan0=vcan0
# 加速回放(2 倍速)
canplayer -I can_log.log vcan0=vcan0=2x
# 无延迟回放(用于快速测试)
canplayer -I can_log.log vcan0=vcan0=0x
# 慢速回放(0.5 倍速)
canplayer -I can_log.log vcan0=vcan0=0.5x接口映射
# 将日志中的 vcan0 映射到 can0
canplayer -I can_log.log vcan0=can0
# 回放多个日志
canplayer -I log1.log -I log2.log vcan0=vcan02.5 cansequence - CAN 帧序列工具
用于发送一系列预定义的 CAN 帧,支持间隔控制。
# 创建序列文件
cat > sequence.txt << 'EOF'
# ID Data Delay(ms)
123 01020304 100
456 AABBCCDD 200
789 11223344 50
EOF
# 播放序列
cansequence -i sequence.txt vcan0
# 循环播放
cansequence -i sequence.txt -l vcan0
# 指定次数播放
cansequence -i sequence.txt -c 10 vcan03. 其他实用工具
3.1 cansniffer - CAN 流量分析
实时分析 CAN 总线流量,显示每条消息的更新间隔。
cansniffer vcan0
# 输出格式:
# vcan0 123 DEADBEEF 0.010s ↑ ← 数据变化
# vcan0 456 00112233 0.050s - ← 无变化
# vcan0 789 AABBCCDD 0.100s ↓ ← 超时3.2 candecoder - CAN 帧解码
使用 DBC 文件解码 CAN 帧。
# 需要先安装 libcanberra-dev
candecoder -c signals.dbc vcan03.3 cantool - CANopen 工具
专门用于 CANopen 调试的命令行工具。
# 读取对象字典值
cantool read -n 2 -i 0x1000 -s 0
# 写入对象字典
cantool write -n 2 -i 0x1400 -s 0 -d 0x024. 实用调试技巧
4.1 实时监控特定节点
# 只监控节点 2 的所有通信
candump vcan0,200:700 # RPDO+TPDO 范围
candump vcan0,500:700 # SDO+SDO 响应范围
candump vcan0,700:7ff # NMT+心跳范围4.2 查找特定数据模式
# 查找包含特定数据的帧
candump vcan0 | grep "DEADBEEF"
# 实时统计帧频率
candump vcan0 | awk '{print $3}' | sort | uniq -c4.3 压力测试脚本
#!/bin/bash
# stress_test.sh - CAN 总线压力测试
INTERFACE="vcan0"
DURATION=60 # 秒
echo "开始压力测试,持续 $DURATION 秒..."
# 启动监控(后台)
candump -l -d $INTERFACE &
# 生成高负载流量
end_time=$(($(date +%s) + $DURATION))
while [ $(date +%s) -lt $end_time ]; do
cansend $INTERFACE $(printf "%03X" $((RANDOM % 2048)))#$(printf "%016X" $RANDOM)
done
# 检查错误统计
ip -details -statistics link show $INTERFACE4.4 自动化心跳检测
#!/bin/bash
# heartbeat_monitor.sh - 心跳监控
INTERFACE="vcan0"
NODE_IDS=(1 2 3 4 5)
TIMEOUT_MS=3000
echo "监控心跳超时 ($TIMEOUT_MS ms)..."
candump -l -d $INTERFACE &
CANDUMP_PID=$!
# 监控进程
declare -A last_seen
for node in "${NODE_IDS[@]}"; do
last_seen[$node]=$(date +%s%3N)
done
check_timeouts() {
local now=$(date +%s%3N)
for node in "${NODE_IDS[@]}"; do
local elapsed=$((now - last_seen[$node]))
if [ $elapsed -gt $TIMEOUT_MS ]; then
echo "[$(date)] 警告: 节点 $node 心跳超时 (${elapsed}ms)"
fi
done
}
trap "kill $CANDUMP_PID; exit" SIGINT
while true; do
check_timeouts
sleep 0.5
done5. 故障排查速查
| 问题 | 命令 | 解释 |
|---|---|---|
| 检查接口是否启动 | ip link show vcan0 | UP 状态表示已启动 |
| 查看总线负载 | ip -details -statistics link show vcan0 | 查看 RX/TX 统计 |
| 测试发送功能 | cansend vcan0 123#DEADBEEF | 无报错则正常 |
| 检查接收功能 | candump vcan0 &; cansend vcan0 123#DEADBEEF | 能看到自己发的帧 |
| 查找错误帧 | candump vcan0 | grep -i error | 搜索错误关键字 |
★ Insight ─────────────────────────────────────
candump -l是最常用的调试命令——所有真实环境调试都应该先记录日志,遇到问题时可以回放分析。- can-utils 的过滤功能强大但容易出错:掩码 0x7ff 只匹配低 11 位,扩展帧需要用 0x1fffffff。
- 压力测试时注意不要使用物理 CAN 接口——高负载的随机帧可能导致实际设备进入错误状态。
─────────────────────────────────────────────────
下一步
→ 03-wireshark-analysis.md —— 学习 Wireshark 协议分析
如果这篇文章对你有帮助,欢迎请我喝杯咖啡 ☕
支付宝
微信