【DBC文件与报文分析】读懂.DBC文件, CAN通信矩阵,报文解析(附源码)
优秀参考文章链接:
—>DBC文件与信号矩阵
CAN 报文字节排列顺序(Intel、Motorola_LSB、Motorola_MSB)
—>C语言解析CAN报文数据
目录
DBC文件分析与总览
DBC文件总览
DBC文件分析CAN通信矩阵
Intel格式
典例
Motorola格式
典例详细解析Motorola格式的报文
DBC文件分析与总览
DBC文件总览
使用CANdb++ (推荐) 打开:
移步:【安装手册】CANdb++ Editor || 【使用手册】CANdb++Editor
使用记事本或**nodepad++**打开:
一个标准CAN帧中包含的信息有,消息ID、报文发送周期、 报文长度、信号信息等。
下面了解可以跳过,暂时没装CANdb++初步接触的可以看下:
1.版本与新符号
version: 版本信息可以为空,也可由用户自定义
new symbol: 随dbc文件自动生成
2.波特率定义 (必须项)
BS_:[baudrate:BTR1, BTR2]
"BS_":CAN网络的波特率,必须存在,[]内容可以省略
3.网络节点定义 (必须项)
BU_:Nodename1 Nodename2 Nodename3...
"BU_":表示网络节点,由用户自定义,需保证节点命名的唯一性
例:
BU_:AVNT ACU HUD ——> 定义了AVNT、ACU、HUD三个网络节点
4.报文帧定义
BO_ MessageId(10进制) MessageName: MessagSize Transmitter
"BO_":关键字,表示报文
"MessageId":报文ID,以十进制表示
"MessageName": 报文名字
"MessagSize":报文数据域字节数,为'无符号整型数据'
"Transmitter": 发送该报文的网络节点,无指定发送节点,则设置为'Vector_XXX'
BO_ 1549 PosLocalD: 4 IFS2000: 表示由IFS2000节点发送,数据域长度为4字节,ID为1549(0x60d),名字为PosLocalD的报文
5.信号定义
SG_SignalName: StartBit|SignalSize@ByteOrder ValueType (Factor, Offset) [Min|Max] Unit Receiver
"SG_":关键字,表示信号
"Signal Name": 信号名称
"StartBit":起始位
"SignalSize":信号长度,单位为:bit
"ByteOrder":字节顺序,0 ——> Motorola格式,1 ——> Inter格式
"valueType": 信号的数值类型,'+' ——> '无符号数', '-' ——> '有符号数'
"Factor":表示因子, "Offset":偏移量
物理值 = 原始值 * Factor + Offset
"Min|Max": 信号的最小值和最大值,为double类型
"Unit": 该信号的单位,为字符串类型
"Receiver": 信号的接收节点,无指定节点,则设置为'Vector_XXX'
例:
SG_ PosLocalDown : 0|32@1- (0.001,0) [-214748.3648|214748.3647] "m" Vector__XXX
表示名为'PosLocalDown'的信号起始位为第0位,信号长度为32位,Inter格式,数值类型为有符号类型数
因子为0.001,偏移量为0,信号取值范围为-214748.3648到214748.3647,信号单位为:'m',无指定接收节点
6.注解部分
CM_Object MessageId/NodeName "Comment"
"cm_": 关键字,表示注解信息
"Object": 注解对象类型,可以是节点"BU_", 报文"BO_", 信号"SG_"
"MessageId/NodeName": 注解对象,若对象类型为信号或者报文,则为报文的ID(10进制);若对象为节点,则为节点的名称
"Comment": 注解的文本
例:
"CM_ SG_ 996 HUD_HeightLv “Control hud height level":
表示对ID为996这条报文下的'HUD_HeightLv'信号进行注解,内容为'Control hud height level'
7.属性定义
BA_DEF_Object AttributeName ValueType Min Max;
BA_DEF_DEF_ AttributeName DefaultValue
"BA_DEF_":关键字,表示属性定义
"Object": 对象,可以是 节点'BU_',报文'BO_',信号'SG_'
"AttributeName":属性名
"ValueType:":数据类型,有'整型'、'字符串'、'浮点型'、'枚举型'
"Min/Max":属性值的取值范围
"BA_DEF_DEF_":关键字,表示定义属性的初始值
"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"
"VAL_":关键字,数值表定义
"MessageId":报文ID(十进制)
"SignalName":信号名
N "DefineN" ....0 "Define0":表示定义的数值表内容
例:
VAL_ 996 HUD_OffSt 1 “Active” 0 “Not Active”:
表示ID为996的报文下名为"HUD_OffSt"信号进行数值表定义,"Active"取代'1',"Not Active"取代'0'
DBC文件分析
虽然能够看到id和对应的data 值, 但是我不知道里面的意思是什么?
这里就需要使用dbc文件来解析。 如果没有dbc文件, 拿到这些报文也不知道是什么意思。
简单介绍一下CANdb++展现的报文信息,详细见文首CANdb++使用手册。
可以通过信号中的定义信息的信息来解析上面的报文值。
Name : 信号的名字
Message: 信号所在的报文名
StartBit: 开始位
Length: 长度
ByteOrder: 排序方式
Factor: 分辨率(就是传输数据时每一位(bit)代表的最小单位数据量)
Offset: 偏移量(偏移量就是在传输数据中加上一个数据量)
Motorola 0
Intel 1
主要就是根据dbc文件中的定义来解析报文
现在要把上图呈现的信号从.dbc文件中解析出来,供实现自动化仿真总线信号使用,比如使用python+支持can收发的硬件即可替代canoe实现信号仿真(性能上不够用,可满足功能测试所需)。
本文将直接把报文解析后串口打印,一目了然!
CAN通信矩阵
在定义CAN通信矩阵/制作/解析dbc文件时,我们需要知道报文的字节排列顺序。
字节的排列顺序有2种,Motorola格式与Intel格式这个决定了信号起始bit, 生成报文计算信号值时的大小端算法。
参考链接:【数据存储】大/小端存储与字节顺序转换函数详解
Intel格式
Intel格式跟小端格式一样,低地址代表低字节,高地址代表高字节。
比如一个信号Intel,它的起始位为3,长度为10,在dbc中它的排列顺序如下所示:
要注意其箭头的增长方向,这样我们在提取该信号的值为
Intel = (byte0 >> 3) + (byte1 << 5)
其中(byte0 >> 3)为低字节的值,(byte1 << 5)为高字节的值。
典例
Intel格式:
信号以低字节低位起始,此处占了12bit, 以第一字节的低bit 0位算起,计12个bit总长度,信号是非连续的(发送的字节序体现出的信号值非连续,但是bit位是由低到高连续的)。
比如我设置续航里程998KM, 信号值在报文中为 E6,03,00,00,00,00,00,00
Motorola格式
Motorola格式跟大端格式一样,低地址代表高字节,高地址代表低字节。
与Intel不一样,Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB,但实际上它们代表的数据结构是一样的,只是表达方式不一样而已,其中Motorola_LSB的起始位是从低字节开始的,而Motorola_MSB的起始位是从高字节开始的。
在dbc中,比如一个Motorola_LSB的信号MotorolaSignal,其起始位为10,长度为10,在dbc中,其排列顺序如下所示:
要注意其箭头的增长方向,这样我们在提取该信号的值为
MotorolaSignal= (byte1 >> 2) + (byte0 << 6)
其中(byte1 >> 2)为低字节的值,(byte0 << 6)为高字节的值。
该MotorolaSignal信号用Motorola_MSB表示则为起始位为3,长度为10,但其值的计算方式跟Motorola_LSB是一样的。
典例
Motorola格式:
信号以高字节低位起始,此处占了12bit, 以第二字节的低bit 12位算起,计12个bit总长度,信号是连续的(此处连续针对低字节在前的字节发送序,参看LSB与MSB)。
比如我设置续航里程998KM, 它的信号值在整条报文中表现为 3E,60,00,00,00,00,00,00
详细解析Motorola格式的报文
开始解析前,先了解一下报文帧。
下表体现了摩托罗拉字节位序的报文发送时的字节序和bit序,一会儿可以帮助我们理解dbc中的定义:
选中灰色对应的是一条报文:
1字节(byte)=8位(bit) 一个字节的数据用十六进制表示只需要2位
报文id 0x123
报文值(长度8字节) 20 02 17 00 00 00 00 07
根据 Motorola 格式,将上面报文值(16进制) 转换成 2进制;
下面的表格中对应的二进制值就是上面报文值对应的值(实际上转换一下就是信号矩阵)。
根据dbc文件中的定义 我们来计算一下 GTS_CRC 这条信号对应的值。
这个信号对应的 StartBit 是8 , length为 8, factor: 1 , offset(偏移量):0
根据排序,对应的值 是下面的表格中的值:
开始取值:取到的对应的二进制的值是: 0000 0010
将 二进制值转换为 十进制值: 0000 0010 = 2(raw_value)
physical_value = raw_value*factor+offset
factor: 1 , offset:0
2 * 1 + 0 = 2 (把原始信号转换物理值)
所以这个信号解析之后的值是 2
代码实现移步:
【解析CAN报文数据矩阵】矩阵信号Intel与Motorola(C语言)代码