
dbc文件的格式、创建以及自动处理
dbc文件格式首先我们来看看dbc文件的格式,我们通过记事本打开在dbc文件,此时界面如下图所示: 如上图所示,一般dbc文件中包含了如下的8种...
dbc文件格式首先我们来看看dbc文件的格式,我们通过记事本打开在dbc文件,此时界面如下图所示:
如上图所示,一般dbc文件中包含了如下的8种信息:1、版本与新符号
2、波特率定义
3、网络节点的定义
4、报文帧的定义
5、信号的定义
6、注解部分
7、属性定义部分
8、数值表部分其中第2点、第3点是必须项,缺少这两项的dbc文件是不能用CANdb++ Editor软件打开的;接下来我们结合例子对dbc文件的这几项信息进行逐步解析介绍。1、版本与新符号如下图,Dbc文件头部包含着”version”与”new symbol”的信息;(1)、 ”version”信息可以为空,也可以由用户自定定义;(2)、 ”new symbol”信息在我们创建dbc文件时就已经自动生成;所以这一部分的信息我们无需过多留意,一般默认即可。2、波特率定义格式如下:BS_:[baudrate:BTR1,BTR2];其中BS_为关键字,用于定义CAN网络的波特率;[ ]内容表示为可选部分,可以省略(如下图例子中即把该部分省略了);但关键字”BS_:”必须存在,省略则会出错。3、网络节点的定义格式如下:BU_:Nodename1 Nodename2 Nodename3 ……其中BU_为关键字,表示网络节点,格式中的Nodename1、Nodename2表示定义的网络节点名字,由用户自己定义;但需保证节点命名的唯一性。如示例中的BU_: AVNT ACU HUD :表示定义了AVNT、ACU、HUD这三个网络节点。4、报文帧的定义格式如下:BO_ MessageId(10进制数表示) MessageName: MessageSize Transmitter1. BO_为关键字,表示报文;2. MessageId为定义的报文ID,是以10进制数表示的;如例子中的996,代表报文ID为0x3E4;3. MessageName表示该报文的名字,命名规则和C语言变量相同;4. MessageSize表示该报文数据域字节数,为无符号整型数据;5. Transmitter表示发送该报文的网络节点;如果该报文没有指定发送节点,则该值需设置为” Vector__XXX”。 如示例中的BO_ 996 HUD_1_B: 8 HUD:表示定义了一条由HUD这个节点发送,数据域长度为8字节,ID为996(0x3E4),名字命名为HUD_1_B的报文。5、信号的定义格式如下:SG_ SignalName : StartBit|SignalSize@ByteOrder ValueType (Factor,Offset) [Min|Max] Unit Receiver1. SG_为关键字,表示信号;2. SignalName、 StartBit、 SignalSize分别表示该信号的名字、起始位、信号长度;3. ByteOrder表示信号的字节顺序:0代表Motorola格式,1代表Inter格式;4. ValueType 表示该信号的数值类型:+表示无符号数,-表示有符号数;5. Factor表示因子,Offset表示偏移量;这两个值于该信号的原始值与物理值之间的转换。 转换如下:物理值=原始值*因子+偏移量;6. Min|Max表示该信号的最小值和最大值,即指定了该信号值的范围;这两个值为double类型;7. Unit表示该信号的单位,为字符串类型;8. Receiver表示该信号的接收节点;若该信号没有指定的接收节点,则必须设置为” Vector__XXX”。如示例中的 SG_ HUD_BrightnessLv : 15|4@0+ (1,0) [0|15] “lv” ACU,AVNT表示定义了一个命名为HUD_BrightnessLv的信号,其起始位是第15位,信号长度4个位;信号是Motorola格式,数值类型为无符号类型数;因子为1,偏移量为0;信号取值范围为0到15;信号单位为字符串”lv”;该信号接收节点为ACU、AVNT这两个节点。6、注解部分格式如下: CM_ Object MessageId/NodeName “Comment”1. CM_为关键字,表示注解信息;2. Object表示进行注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”;3. MessageId/NodeName 表示进行注解的对象,若前面的对象类型是信号或者报文,则这里的值应为报文的ID(10进制数表示);若前面的对象类型为节点,则这里的值应为节点的名字;4. Comment表示进行注解的文本信息;如示例中的 CM_ SG_ 996 HUD_HeightLv “Control hud height level”;表示对ID为996(0x3E4)这条报文下的名为”HUD_HeightLv ”的信号进行注解说明,说明的内容为"Control hud height level"。 又如 CM_ BU_ HUD “Head Up Display";表示对HUD这个节点进行注解说明,说明的内容为" Head Up Display "。7、属性定义部分格式如下:BA_DEF_ Object AttributeName ValueType Min Max;BA_DEF_DEF_ AttributeName DefaultValue;1. BA_DEF_为关键字,表示属性定义;2. Object表示属性定义的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)等;3. AttributeName表示进行定义的属性名字;4. ValueType表示属性值的类型,可以是整型、字符串、浮点型、枚举类型等;5. Min/Max表示属性值的上下最值,即指定了取值范围(字符串类型没有此项)。6. BA_DEF_DEF_为关键字,表示定义属性的初始值;7. DefaultValue表示该属性的初始值。如示例中的 BA_DEF_ SG_ “MyTry” INT 0 11; BA_DEF_DEF_ “MyTry” 0;表示对定义了一个针对信号类型的属性,属性名为”MyTry”,属性值是整型数据,取值范围在0到11之间,初始值为0。8、数值表部分格式如下:VAL_ MessageId SignalName N “DefineN” …… 0 “Define0”;1. VAL_为关键字,表示数值表定义;2. MessageId表示该信号所属的报文ID(10进制数表示);3. SignalName表示信号名;4. N “DefineN” …… 0 “Define0”表示定义的数值表内容,即该信号的有效值分别用什么符号表示 。如示例中的 VAL_ 996 HUD_OffSt 1 “Active” 0 “Not Active”;表示对ID为996(0x3E4)的这条报文下的,一个命名为”HUD_OffSt”的信号,进行其数值表的定义;用”Active”取代1;用”Not Active”取代0。dbc文件的创建1.打开candb++软件,单击菜单File,单击CreateDatabase,选择第一个模板点击OK,命名dbc文件进入文件编辑。
2.右键单击Message,选择New,在Message的Definition界面中根据整车通讯协议定义对Message进行编辑;主要包括Message_Name,CAN报文类型,ID和DLC。
3.新建完message之后,需要新建signal了。右键单击Signal,选择New,在Signal的Definition界面中根据整车通讯协议定义对Signal进行编辑,包括名称、长度、字符类型等属性。
4.完成message和signal之后,就需要将signal映射到message了。单击Message,选择Add,选择对应的Message并单击OK,将Signal关联至对应ID的Message,还需要设置signal的startbit,接收节点和发送节点。
自动操作dbc文件canmatrix这个开源的 python dbc 库能够加载、编辑dbc文件并将其导出为其他格式。还可以支持ldf、arxml、json、csv等文件格式。安装canmatrix后,在\Python\PythonXX\Scripts路径下,会有一个canconvert.exe。可以直接在命令行中:输入"canconvert xxx.xls xxx.dbc"将xls转成dbc格式。
对于canmatrix的功能介绍如下:
1. 加载dbc
import canmatrix# 加载DBC文件dbc = canmatrix.formats.loadp("test.dbc")dbc_matrix = dbc.get("")print(type(dbc), dbc)canmatrix.formats.loadp(file)用于load不同格式的文件。打印其信息,是一个字典类型。matrix = dbs.get('')print(type(matrix), matrix)for k, v in matrix.__dict__.items(): print(k, v)获取字典中的value,其类型是CanMatrix,dbc中的信息都在这里。打印其中包含的信息,如下所示。2.获取dbc中所有的ecu节点import inspectfor ecu in dbc_matrix.ecus: print(type(ecu), inspect.getmembers(ecu))3.获取帧信息报文的帧信息的类型是Frame,一般用到:
name:报文的名称
arbitration_id.id:报文的id
transmitters:发送报文节点
receivers:接收报文的节点
signals:报文中的信号
signalGroups:报文中的signalGroups
cycle_time:报文周期
for msg in dbc_matrix.frames: print(type(msg), msg.__dict__)4,获取signal信息signal的信息一般用到:
name:信号名称
start_bit:在layout中的起始位
size:长度(bit)
is_little_endian:Motorola(Big)和Intel(Little)格式
is_signed:有无符号
offset和factor:偏移和系数,用于转换成物理值
min和max:最小值和最大值
is_multiplexer:多路复用信号的multiplexor signal
mux_val:multiplex value
multiplex:和is_multiplexer、mux_val两个量信息是重复的。当信号是multiplexor signal时,这个量是字符串“Multiplexor”;当信号是multiplexed signal时,这个量是multiplex value。
for signal in dbc_matrix.signals: print(type(signal), inspect.getmembers(signal)) #2 指定帧后加载信号for msg in dbc_matrix.frames: print(type(msg), msg.__dict__) for signal in msg.signals: print(type(signal), inspect.getmembers(signal))5. 获取信号组
for signalGroup in msg.signalGroups: print(type(signalGroup), signalGroup.__dict__) for k, v in signalGroup.__dict__.items(): print(k, v)
最后推荐一本由机械工业出版社出版、由同济大学汽车学院王学远博士和魏学哲教授翻译的《车载网络通信技术》书籍。
-end-
分享不易,恳请点个【👍】和【在看】