一个用于合并多个CAN总线DBC(Database CAN)文件的工具。
- 智能合并:以帧ID(CAN ID)为标准判断重复,有重复ID的帧只保留第一个出现的
- 自动过滤:自动删除所有CAN ID为0的帧及其中的所有信号
- 完整性保留:保留DBC文件的所有必要定义部分(VERSION、NS_、BS_、BU_、VAL_TABLE_、VAL_、SIG_GROUP_等)
- 编码支持:支持多种文件编码(UTF-8、GBK、GB2312等)
- 详细统计:显示合并过程中的详细统计信息
- 自动识别:根据帧命名规则自动识别发送方和接收方
- 智能补齐:自动补齐缺失的帧发送方、接收方和信号接收方
- 节点管理:自动添加缺失的ECU节点定义
- 详细报告:提供完整的问题诊断和修复报告
- Python 3.10或更高版本
- uv(推荐的Python包管理工具)
# 使用uv安装(推荐)
uv pip install -e .
# 或使用pip安装
pip install -e .# 合并3个DBC文件
uv run dbc-merge -i dbc/CANConfig_1.dbc -i dbc/CANConfig_2.dbc -i dbc/CANConfig_3.dbc
# 指定输出文件
uv run dbc-merge -i dbc/CANConfig_1.dbc -i dbc/CANConfig_2.dbc -i dbc/CANConfig_3.dbc -o dbc/my_merged.dbc
# 显示详细信息
uv run dbc-merge -i dbc/CANConfig_1.dbc -i dbc/CANConfig_2.dbc -i dbc/CANConfig_3.dbc -v
# 仅分析不生成文件
uv run dbc-merge -i dbc/CANConfig_1.dbc -i dbc/CANConfig_2.dbc -i dbc/CANConfig_3.dbc --dry-run -v# 检查DBC文件的ECU收发关系
uv run dbc-check-ecu -i dbc/CANConfig.dbc
# 检查并修复(保存到 CANConfig.dbc.fixed.dbc)
uv run dbc-check-ecu -i dbc/CANConfig.dbc --fix
# 检查并修复(保存到指定文件)
uv run dbc-check-ecu -i dbc/CANConfig.dbc --fix -o dbc/CANConfig_fixed.dbc
# 显示详细输出
uv run dbc-check-ecu -i dbc/CANConfig.dbc --fix -v帧命名规则:
- DPGK发出的帧:
Frm_DPGK_<接收节点>_<功能描述>- 示例:
Frm_DPGK_VLPD_status→ DPGK发送给VLPD
- 示例:
- 其他节点发出的帧:
Frm_<发送节点>_<功能描述>_<其他>- 示例:
Frm_WPCU_water_temp→ WPCU发送给DPGK
- 示例:
- 特殊规则:ZDCU是占位符,代表除DPGK外的所有节点
Frm_DPGK_ZDCU:DPGK广播给所有其他节点- 工具会根据帧ID类型(标准/扩展)智能选择接收节点列表
dbc-merge命令:
-i, --input:输入的DBC文件路径(可指定多个,必需)-o, --output:输出的DBC文件路径(默认:dbc/CANConfig_merged.dbc)-v, --verbose:显示详细输出,包括所有帧ID列表--dry-run:仅执行分析,不生成输出文件--help:显示帮助信息
dbc-check-ecu命令:
-i, --input:输入的DBC文件路径(必需)-o, --output:输出的DBC文件路径(默认:输入文件名.fixed.dbc)--fix:执行修复操作,默认仅检查-v, --verbose:显示详细输出,包括所有修改的详情--help:显示帮助信息
from pathlib import Path
from dbc_utils.merger import DBCMerger
# 创建合并器
merger = DBCMerger(
[
Path("dbc/CANConfig_1.dbc"),
Path("dbc/CANConfig_2.dbc"),
Path("dbc/CANConfig_3.dbc"),
],
Path("dbc/CANConfig_merged.dbc")
)
# 执行合并
merged = merger.merge()
# 保存文件
merger.save()
# 查看统计
stats = merger.get_statistics()
print(f"合并后帧数: {stats['total_frames']}")
print(f"节点数: {stats['unique_nodes']}")from pathlib import Path
from dbc_utils.ecu_checker import ECUTransceiverChecker
# 创建检查器
checker = ECUTransceiverChecker(Path("dbc/CANConfig.dbc"))
# 执行检查
report = checker.check()
print(f"发现 {len(report.issues)} 个问题")
print(f"缺失的ECU: {report.missing_ecus}")
# 执行修复
fix_report = checker.fix(Path("dbc/CANConfig_fixed.dbc"))
print(f"更新了 {fix_report.frames_updated} 个帧")
print(f"添加了 {fix_report.ecus_added} 个ECU节点")- 重复判断标准:以帧ID(CAN ID)为判断重复的标准,有重复ID的帧只保留第一个出现的
- 删除规则:完全删除所有CAN ID为0的帧及其中的所有信号
- 头部信息:使用第一个输入文件的VERSION、NS_、BS_等头部信息
- 节点合并:合并所有文件中的节点(BU_),去重后保留
- 值表合并:按名称合并值表(VAL_TABLE_),去重后保留
- 枚举值处理:只保留合并后帧中存在的信号的枚举值(VAL_)
- 信号组处理:只保留合并后帧中存在的信号的信号组(SIG_GROUP_)
本项目遵循特定的帧命名规范,用于标识帧的发送方和接收方:
基本格式:Frm_<发送方>_<接收方/功能>_<描述>
-
DPGK发送的帧
- 格式:
Frm_DPGK_<接收节点>_<功能描述> - 示例:
Frm_DPGK_VLPD_status→ DPGK发送给VLPD - 发送方:DPGK
- 接收方:第三个字段指定的节点
- 格式:
-
其他节点发送的帧
- 格式:
Frm_<发送节点>_<功能描述>_<其他> - 示例:
Frm_WPCU_water_temp→ WPCU发送给DPGK - 发送方:第二个字段指定的节点
- 接收方:DPGK(默认,不显式写出)
- 格式:
-
特殊节点ZDCU
- 格式:
Frm_DPGK_ZDCU或Frm_DPGK_ZDCU_<功能> - ZDCU是占位符,代表除DPGK外的所有节点
- 发送方:DPGK
- 接收方:根据帧ID类型自动选择
- 标准帧ID(CAN ID ≤ 0x7FF):接收方为使用标准帧的节点
- 扩展帧ID(CAN ID > 0x7FF):接收方为使用扩展帧的节点
- 格式:
工具会根据以下规则智能处理ZDCU:
-
ZDCU不作为ECU节点添加
- ZDCU是逻辑占位符,不会被添加到DBC文件的ECU节点列表中
-
自动展开接收方列表
- 工具会分析DBC文件中所有节点的帧ID使用情况
- 根据当前帧的ID类型(标准/扩展)选择合适的接收节点
-
示例
# 输入:Frm_DPGK_ZDCU (CAN ID: 0x501,标准帧) # 输出: # 发送方:DPGK # 接收方:[WPCU, VLPD, SPCU, BKCU, STCU] # 使用标准帧的节点
dbc_utils/
├── pyproject.toml # 项目配置
├── README.md # 项目文档
├── dbc/ # DBC文件目录
│ ├── CANConfig_1.dbc
│ ├── CANConfig_2.dbc
│ ├── CANConfig_3.dbc
│ └── CANConfig_merged.dbc # 输出文件
└── src/
└── dbc_utils/
├── __init__.py # 包初始化
├── cli.py # DBC合并命令行接口
├── merger.py # DBC合并逻辑(基于canmatrix)
├── ecu_checker.py # ECU收发关系检查器
├── ecu_cli.py # ECU检查命令行接口
└── utils.py # 工具函数
使用ruff进行代码检查:
uv run ruff check .uv run ruff format .DBC文件是Vector CAN数据库格式,主要包含以下部分:
VERSION:版本信息NS_:命名空间定义BS_:位定时配置BU_:节点定义VAL_TABLE_:值表定义BO_:帧定义(消息对象)SG_:信号定义VAL_:枚举值定义SIG_GROUP_:信号组定义BA_DEF_:属性定义CM_:注释
- DBC文件可能包含中文注释,工具支持多种编码(UTF-8、GBK、GB2312、latin1)
- 输出文件统一使用UTF-8编码
- 使用集合(Set)跟踪已见过的CAN ID,确保O(1)查找性能
- 按文件顺序处理,确保第一个出现的帧被保留
- 在合并引用(VAL_、SIG_GROUP_)时验证信号是否存在,避免无效引用
假设有三个DBC文件需要合并:
# 合并文件
uv run dbc-merge \
-i dbc/CANConfig_1.dbc \
-i dbc/CANConfig_2.dbc \
-i dbc/CANConfig_3.dbc \
-v输出示例:
🚀 开始合并 3 个DBC文件...
输入文件:
- dbc/CANConfig_1.dbc
- dbc/CANConfig_2.dbc
- dbc/CANConfig_3.dbc
输出文件: dbc/CANConfig_merged.dbc
✅ 合并完成!
总帧数: 68
节点数: 15
值表数: 3
枚举值数: 45
信号组数: 12
过滤的CAN ID为0的帧: 0
去除的重复帧: 4
💾 已保存到: dbc/CANConfig_merged.dbc
MIT License
Created with Claude Code