DBC文件解析
DBC文件在汽车电子和嵌入式系统中非常重要,主要用于定义和描述 CAN总线上的消息和信号。一般我们需要使用canoe,CANalyzer等专业的工具来打开dbc文件,对dbc文件进行配置或者查看。但是作为程序员,可能没有这些工具,我们也可以直接通过vscode打开dbc文件,显示如下。为了工作上的便利,我们需要看懂这份dbc文件。。
文章目录
1. 背景
DBC文件在汽车电子和嵌入式系统中非常重要,主要用于定义和描述 CAN总线上的消息和信号。以下是 DBC 文件的主要用途和重要性:
- 定义消息格式:DBC 文件详细描述了 CAN 总线上各个message的格式,包括message ID、名称、长度、发送节点等信息,这些定义确保了不同设备之间的通信一致性和可靠性;
- 信号映射:每个message可以包含多个signal,DBC 文件定义了这些signal的名称、位置、数据类型和单位;
- 标准化通信:在复杂的汽车电子系统中,多个 ECU(Electronic Control Unit)需要协同工作。DBC 文件提供了一个标准化的通信规范,确保所有设备都能正确理解和处理数据;
- 工具支持:许多专业的 CAN 分析和仿真工具(如 CANoe、CANalyzer 等)都支持 DBC 文件。这些工具可以读取 DBC 文件并提供强大的数据可视化和分析功能。开发者可以使用这些工具进行系统测试、故障诊断和性能优化;
- 文档化:DBC 文件作为一种文档,记录了整个 CAN 网络的配置和通信协议。这对于项目管理和团队协作非常有用。
一般我们需要使用canoe,CANalyzer等专业的工具来打开dbc文件,对dbc文件进行配置或者查看。但是作为程序员,可能没有这些工具,我们也可以直接通过vscode打开dbc文件,显示如下。为了工作上的便利,我们需要看懂这份dbc文件。本文将逐个分析dbc中的常用的标识符。
VERSION "v00.03.00_00"
NS_ :
NS_DESC_ # 也是用于注释,与CM_类似,但更加专业,一般用于专业文档生成
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER_
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_
BS_:
BU_: ECU1 ECU2 ECU3 ECU4
BO_ 510 DCM_01: 8 ECU1
SG_ DoorLockFrntRiReq : 39|2@0+ (1,0) [0|3] "" ECU2
SG_ DoorLockFrntLeReq : 7|2@0+ (1,0) [0|3] "" ECU2
BO_ 180 TimeSync: 8 ECU1
SG_ NSec m40 : 15|32@0+ (1,0) [0|4294967295] "ns" ECU2
SG_ Sec m32 : 15|32@0+ (1,0) [0|4294967295] "ms" ECU2
...
SG_ TimeDmain : 47|4@0+ (1,0) [0|15] "" ECU2,ECU4
SG_ Type M : 7|8@0+ (1,0) [0|255] "" ECU2
BO_TX_BU_ 280: BGW, CCU
CM_ "车辆CAN网络定义文件\n版本:2.1"; # 全局网络注释
CM_ BU_ EngineControl "发动机控制单元\n供应商:xxx"; # 节点注释
CM_ BO_ 100 "车辆状态报文\n发送周期:100ms\n优先级:高";# 报文注释
CM_ SG_ 100 VehicleSpeed "实际车速信号\n数据来源:轮速传感器\n精度:±0.5km/h"; #信号注释,
CM_ EV_ AmbientTemp "环境温度变量\n采集频率:1Hz"; # 环境变量注释
CM_ SG_ 510 DoorLockFrntRiReq "Front-Right Door lock Request"; # 信号注释
# 定义节点属性,hex
BA_DEF_ BU_ "Address" HEX 0 255;
# 定义消息周期属性(整型)
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 10000;
# 定义信号状态属性(枚举型)
BA_DEF_ SG_ "SignalStatus" ENUM "ENABLED","DISABLED","TEST_ONLY";
# 全局描述属性
BA_DEF_ "Description" STRING;
#设置默认值
BA_DEF_DEF_ "Address" 0; #设置默认值为0
BA_DEF_DEF_ "GenMsgCycleTime" 100; # 消息周期默认100ms
BA_DEF_DEF_ "SignalStatus" "DISABLED"; #信号状态默认禁用
BA_DEF_DEF_ "Description" ""; # 全局描述默认空
#属性赋值
BA_ "Address" BU_ ECU1 7;
BA_ "GenMsgCycleTime" BO_ 0x101 200; #为消息0x101设置周期200ms
BA_ "GenMsgCycleTime" BO_ 0x102 100; #为消息0x102设置周期100ms
BA_ "SignalStatus" SG_ 0x101 VehicleSpeed "ENABLED"; #为车速信号启用
BA_ "Description" BU_ EngineControl "ECU v2.3"; #设置节点描述
VAL_ 510 DoorLockFrntRiReq 3 "Reserved" 2 "Lock" 1 "Unlock" 0 "No request" ;
2. DBC文件详解
2.1 version
version信息一般由用户定义,也可以为空,在创建dbc的时候自动生成。
2.2 NS_
新符号,NS_ 部分定义了 DBC 文件中使用的各种符号和标识符,创建dbc文件时自动生成,无需修改。
2.3 BS_
波特率定义,格式:BS_: [baudrate:BTR1,BTR2]
[]内容表示为可选部分,但是必须配置BS_,否则会出错。波特率一般由can模块自己配置,不在dbc中配置。
2.4 BU_
网路节点定义,用于声明当前can网络中存在哪些can节点。
例子:
BU_: ECU1,ECU2,ECU3,ECU4
2.5 BO_
报文帧定义,格式:BO_: MessageID MessageName : MessageSize Transmitter
| 关键字 | 描述 |
|---|---|
| BO_ | 关键字,表示当前描述报文 |
| MessageID | 报文ID,10进制表示 |
| MessageName | 报文名称 |
| MessageSize | 报文长度,普通can报文最大长度为8, canfd报文长度为64 |
| Transmitter | 报文的发送节点,若没有指定发送节点可以使用Vector__XXX代替 |
例子:
BO_ 510 DCM_01: 8 ECU1 # ECU1发送DCM_01报文,报文ID为510,长度为8
2.6 SG_
信号的定义,格式:SG_ SignalName [SigTypeDefinition] : StartBit|SignalSize@ByteOrder Sign (Factor,Offset) [Min|Max] “Unit” Receiver
| 关键字 | 描述 |
|---|---|
| SG_ | 关键字,表示当前描述信号 |
| SignalName | signal name |
| SigTypeDefinition | 多路复用标识,可选项,空表示普通信号;M表示多路复用信号;m[Value]表示特定多路值下的信号 |
| StartBit | 信号在消息中的起始位 |
| SignalSize | 信号占用的位数 |
| ByteOrder | 字节序:0表示大端序(Motorola格式,高位在前),1表示小端序(Intel格式,低位在前) |
| Sign | 符号类型:+表示无符号数, -表示有符号数 |
| Factor,Offset | 物理值转换公式:物理值 = (原始值 × Factor) + Offset |
| [Min Max] | 信号物理值的有效范围 |
| unit | 物理值单位(字符串) |
| Receiver | 接收该信号的节点列表(逗号分隔),若不指定可以使用Vector__XXX代替 |
例子:
BO_ 510 DCM_01: 8 ECU1
SG_ DoorLockFrntRiReq : 39|2@0+ (1,0) [0|3] "" ECU2
# 定义了一个普通信号DoorLockFrntRiReq,其实地址为39,长度为2,
# 0是大端模式,+表示无符号数
# 因子为1,偏移量为0,物理值=(原始值 * 1) + 0
# 范围为0-3
# 无单位
# 接受节点是ECU2
# can time sync报文复用配置
BO_ 180 TimeSync: 8 ECU1
SG_ NSec m40 : 15|32@0+ (1,0) [0|4294967295] "ns" ECU2
SG_ Sec m32 : 15|32@0+ (1,0) [0|4294967295] "ms" ECU2
...
SG_ TimeDmain : 47|4@0+ (1,0) [0|15] "" ECU2,ECU4
SG_ Type M : 7|8@0+ (1,0) [0|255] "" ECU2
# Type为复用信号,若Type值为40,则起始地址15长度32的数据表示NSec,
# 若Type值为30,则起始地址15长度32的数据表示Sec
# 在复用信号中也可以定义普通信号,也就是无论type是什么,起始地址为47长度为4的数据都是timeDomain
# 一个报文中的信号可以是不同的接收节点,这里只是举例子,并不是合理的配置
2.7 BO_TX_BU_
报文存在多个发送节点,使用该字段声明,格式:BO_TX_BU_ MessageId:Node1,Node2…
| 关键字 | 描述 |
|---|---|
| BO_TX_BU_ | 关键字,用于声明某报文存在多个发送节点 |
| MessageID | 报文ID,10进制表示 |
| MessageId | 报文ID,10进制,一般是在BO_中已经定义的变量 |
| Node1,Node2… | 发送节点名称 |
例子:
BO_ 510 DCM_01: 8 ECU1
SG_ DoorLockFrntRiReq : 39|2@0+ (1,0) [0|3] "" ECU2
SG_ DoorLockFrntLeReq : 7|2@0+ (1,0) [0|3] "" ECU2
BO_TX_BU_ 510 : ECU1,ECU3; #该报文的发送节点可以是ecu1,也可以是ecu3
2.8 CM_
注释,格式:CM_ ObjectType ObjectIdentifier “CommentText”;,NS_DESC_格式与CM_格式一致,CM_更加自由些,一般dbc中多使用CM_
| 关键字 | 描述 |
|---|---|
| CM_ | 关键字,当前为注释语句 |
| ObjectType | 注释对象类型,可以是BU_节点,BO_报文,SG_信号,EV_环境变量,空值表示全局网络 |
| ObjectIdentifier | 对象标识符,与不同的ObjectType相对应 |
| CommentText | 注释内容 |
例子:
CM_ "车辆CAN网络定义文件\n版本:2.1"; # 全局网络注释
CM_ BU_ EngineControl "发动机控制单元\n供应商:xxx"; # 节点注释
CM_ BO_ 100 "车辆状态报文\n发送周期:100ms\n优先级:高";# 报文注释
CM_ SG_ 100 VehicleSpeed "实际车速信号\n数据来源:轮速传感器\n精度:±0.5km/h"; #信号注释,报文100中存在一个signal为VehicleSpeed
CM_ EV_ AmbientTemp "环境温度变量\n采集频率:1Hz"; # 环境变量注释
CM_ SG_ 510 DoorLockFrntRiReq "Front-Right Door lock Request"; # 信号注释
2.9 特征属性部分
在 DBC 文件中,BA_DEF、BA_DEF_DEF 和 BA_ 共同构成了属性定义系统,用于为 CAN 网络中的对象(节点、消息、信号等)添加自定义属性。
2.9.1 BA_DEF_
属性定义,定义属性的名称、数据类型和约束条件语法,格式:BA_DEF_ ObjectType “AttributeName” ValueType Min Max
| 关键字 | 描述 |
|---|---|
| BA_DEF_ | 关键字,定义新属性 |
| ObjectType | 定义属性类型,BU_节点,BO_报文,SG_信号,或者为空表示全局属性 |
| “AttributeName” | 属性名称 |
| ValueType | 属性类型,可以是INT,FLOAT,STRING,ENUM,HEX |
| Min Max | 值范围,数值类型[min, max],枚举类型,使用逗号隔开,string类型可以为空 |
2.9.2 BA_DEF_DEF_
默认值定义,对于BA_DEF_定义的属性设置默认值,格式:BA_DEF_DEF_ “AttributeName” DefaultValue;
| 关键字 | 描述 |
|---|---|
| BA_DEF_DEF_ | 关键字,为属性设置默认值 |
| “AttributeName” | 属性名称 |
| DefaultValue | 默认值 |
2.9.3 BA_
属性赋值,格式:BA_ “AttributeName” ObjectType ObjectID Value;
| 关键字 | 描述 |
|---|---|
| BA_ | 关键字,属性赋值 |
| AttributeName | 属性名称 |
| ObjectType | 属性类型,BU_节点,BO_报文,SG_信号,或者为空表示全局属性 |
| ObjectID | 对象ID,BU_:节点名称,BO_:消息ID,SG_:消息ID+信号名 |
| Value | 具体的值 |
例子:
# 定义节点属性,hex
BA_DEF_ BU_ "Address" HEX 0 255;
# 定义消息周期属性(整型)
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 10000;
# 定义信号状态属性(枚举型)
BA_DEF_ SG_ "SignalStatus" ENUM "ENABLED","DISABLED","TEST_ONLY";
# 全局描述属性
BA_DEF_ "Description" STRING;
#设置默认值
BA_DEF_DEF_ "Address" 0; #设置默认值为0
BA_DEF_DEF_ "GenMsgCycleTime" 100; # 消息周期默认100ms
BA_DEF_DEF_ "SignalStatus" "DISABLED"; #信号状态默认禁用
BA_DEF_DEF_ "Description" ""; # 全局描述默认空
#属性赋值
BA_ "Address" BU_ ECU1 7;
BA_ "GenMsgCycleTime" BO_ 0x101 200; #为消息0x101设置周期200ms
BA_ "GenMsgCycleTime" BO_ 0x102 100; #为消息0x102设置周期100ms
BA_ "SignalStatus" SG_ 0x101 VehicleSpeed "ENABLED"; #为车速信号启用
BA_ "Description" BU_ EngineControl "ECU v2.3"; #设置节点描述
2.10 VAL_
数值表,赋予信号不同的值具体的含义,格式:VAL_ MessageId SignalName N “DefineN” …… 0 “Define0”
| 关键字 | 描述 |
|---|---|
| VAL_ | 关键字,数值表 |
| MessageId | 报文ID,十进制 |
| SignalName | 信号名称 |
| N “DefineN” …… 0 “Define0”; | 不同数值代表的含义 |
例子:
BO_ 510 DCM_01: 8 ECU1
SG_ DoorLockFrntRiReq : 39|2@0+ (1,0) [0|3] "" ECU2
SG_ DoorLockFrntLeReq : 7|2@0+ (1,0) [0|3] "" ECU2
CM_ SG_ 510 DoorLockFrntRiReq "Front-Right Door lock Request";
VAL_ 510 DoorLockFrntRiReq 3 "Reserved" 2 "Lock" 1 "Unlock" 0 "No request" ;
# 报文ID为510的报文中存在一个docklock信号,表示front-right lock request
# 2表示lock,1表示unlock,0表示没有request,3保留
总结
至此,我们已经初步了解dbc文件如何解读,后续我会基于stm32做一个demo,涉及到can,串口等驱动,并且按照autosar框架进行组织,并在这个小demo中增加DBC解析脚本,敬请期待!
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)