前言
控制器局域网总线(CAN,Controller Area Network)是一种用于实时应用的串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。其已经在汽车业、航空业、工业控制、安全防护等领域中得到了广泛应用。(咳咳…水一段凑凑字数)
正因CAN总线在国际中有这相当重要的地位,分析CAN报文也成为相关行业工程师所要掌握必备技能,但是想要在数据繁多的CAN总线中找到正确的信号,并且正确的获取其含义却有这相当的难度。为了有效地管理和解析CAN总线上的数据,开发工程师使用数据库文件来定义和解释这些数据,即所谓的CAN数据库文件或DBC文件(DataBase for CAN)。DBC中详细定义了CAN通信的相关信息,比如消息名,消息ID,信号名,信号的布局等等。
本篇博客(水文)将以Database Editor(dbc编辑器)工具协助理解DBC文件(.dbc)中语句含义。
DBC文件基础模板
基础模板就是空的dbc啦,也就是至少需要包括以下内容。
编辑器创建DBC
首先通过dbc编辑器随便编辑几条报文,当然如果手头有dbc就不用重新创建了,直接打开来观察。
虽然有些属性比较少用到,但是为了学习还是应该尽可能涵盖多的情况…瞎点一通。
这里的dbc是经过编辑器渲染的,我们可以很容易的知道每条报文的解析规则,但是如果要在自己的程序中导入dbc文件,从而在自己的上位机上实现更为美观的,更为复杂数据分析图,就需要程序员理解dbc文本的语法格式(直接使用第三方的轮子就当我没说…)。
DBC文件内容解析
通过文本阅读器(TXT,Notepad++)打开刚编辑的dbc文件。可以看到与基础模板相比多了几行语句,这些语句即代表了刚编辑的CAN报文信息。
下面将会把dbc文件中语句分为三部分(自定义的)进行逐一讲解。
第一部分博主愿称它为“结构语句部分”,主要是描述dbc的版本,新符号的声明,以及一些基础信息(就是没有了不行,但是好像作用不大的部分)
VERSION “”
顾名思义dbc的版本,在开发过程中可能会对dbc进行频繁的修改,用以区分相同名称的dbc。
NS_ :
用于声明部分新定义的关键字,通过缩进方式表示包含关系。
BS_:
描述波特率信息,已经弃用,但是仍是基础结构,不能去掉。
BU_:
定义CAN节点信息,主要是告诉工程师,该DBC中描述了哪些CAN节点的数据信息,如BU_: Node1 Node2 (通过一个空格分隔,而不是逗号),表示包含 Node1 Node2两个节点…(但是感觉好像也没啥用)
VERSION "V123"
NS_ :
NS_DESC_
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_: Node1 Node2
第二部分是“CAN数据信息部分”,包含消息名,消息ID,信号名等等。
1、以BO_ 关键字开头的语句是报文信息,ID由32位的整数表示,扩展帧(ID占29位,最高3位为标志位)在最高位置1,例如
编辑器里设置ID为"213984291",即十六进制表达为"0cc12423"
dbc中则是"2361467939" ,即十六进制表达为"8cc12423"
将编辑器和dbc中的ID转成二进制看就是最高位被置1
语法:(关键字之间以单空格分隔,后续不再提醒)
BO_ ID 消息名: 数据长度 节点名
2、以 SG_ 关键字开头的语句是信号信息,它是 BO_ 的子语句(有缩进)
当存储格式为Intel(即是@后为1)时,语句中 “起始/结束位” 为起始位.当Motorola(即是@后为0)时,“起始/结束位” 为结束位
当信号类型为Unsigned时,“信号类型” 为正号(+),其他类型为负号(-)。
当模式类型为Signal(没有多路复用)时, “模式类型” 可省略。当模式类型为Multiplexor时,“模式类型” 为 M,多路复用的应用:
如设置 NewSignal_0004 M,当该信号的值为1时,NewSignal_0003 m1 生效,为5时,NewSignal_0005 m5。
(Vector__XXX表示该报文没有指定发送节点)
语法:
SG_ 信号名 模式类型 : 起始/结束位|数据长度@存储格式 信号类型 (因数,偏移) [最小值|最大值] “单位” 节点名
BO_ 1 message1: 8 Node1
SG_ s1 : 7|8@0+ (1,0) [0|0] "V" Vector__XXX
SG_ s2 : 15|16@0- (0.1,-0.6) [-0.6|211] "C" Vector__XXX
SG_ NewSignal_0003 m1 : 24|8@1- (1,0) [0|0] "" Vector__XXX
SG_ NewSignal_0004 M : 32|8@1- (1,0) [0|0] "" Vector__XXX
SG_ NewSignal_0005 m5 : 43|14@0+ (-1,40) [40|100] "" Vector__XXX
BO_ 2 message002: 6 Vector__XXX
BO_ 2361467939 Message_0003: 16 Node2
第三部分是“补充信息部分”,对第二部分的信息进行补充。每条语句以分号(;)结尾。
以CM_ 关键字开头是对报文或信号的Comment属性进行补充编辑。
以VAL_ 关键字开头是对信号的Value属性进行补充编辑。
以SIG_VALTYPE_ 关键字开头是对**“信号类型”** 的补充描述(负号情况的补充,Signed不需要补充),值为1代表是Float,值为2代表是Double;
语法:
CM_ BO_ ID “内容”;
CM_ SG_ ID 信号名 “内容”;
VAL_ ID 信号名 值1 “Value名1” 值2 “Value名2”;
SIG_VALTYPE_ ID 信号名 : 值;
CM_ BO_ 1 "123456";
CM_ SG_ 1 s1 "11;213";
CM_ SG_ 1 s2 "";
CM_ BO_ 2 "147258";
CM_ BO_ 2361467939 "369";
VAL_ 1 s2 5 "Value_0012" 1 "Value012" ;
SIG_VALTYPE_ 1 NewSignal_0003 : 1;
SIG_VALTYPE_ 1 NewSignal_0004 : 2;