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解析脚本,敬请期待!

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐