为啥会写这么一篇东西捏,看起来好像没什么用,但碰到问题的时候,你就不得不打开这篇东西了。
问题现象
DBC文件一般是OEM搞的,有些人会规规矩矩搞,有些人不按套路出牌,就会把DBC文件搞得很恶心,我最近就遇到这么个问题。
DBC文件用DBCdb++打不开
里面有个下面的提示,告诉我多少行有个这样的信号没有定义。
问题分析
看着我就蒙了,我都打不开这文件,咋知道怎么把你修好?
问给我这个文件的同学,同学说加载进TSMaster就行,加载进去,TSMaster还真能解析,见了鬼了。
但是我有个关于网络管理的问题分析,需要在这个DBC文件里面加一条唤醒报文,这样才能把唤醒报文解析得出来。我都打不开这报文,你说这有啥用,我得先把这份DBC文件给维修好,才能打开它来加信号。
DBC文件的本质
就是txt一样的记事本,所以用记事本打开也可以,里面主要就下面这几个内容。
我是看vector标准才知道的,网上都是要收费的,我刚上传了个免费版,查查我名字会有个DBC文件格式解析(免费).rar的资源,这个会更全一点,是英文版的。
DBC文件结构
结构就是这样,里面有些是未必会有的,下面专挑常用的讲。
版本
一般就是空的
VERSION ""
新符号
NS_ 开头,没啥用,就是个固定格式。
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_:就是波特率,在旧版里面就有用,现在新的已经没用了,不过格式当中还留着。
BS_:
网络节点
BU_就是网络节点,后面就是节点的名字,就全写上去。
BU_: IVI IC HUD ALC
报文
接下来会有一堆BO_开头的段落,这就是报文,一个段落一个报文,里面每个SG_就是一个信号。
BO_ 1566 NM_Wakeup_Message: 8 ALC
SG_ NM_Wakeup_Signal : 0|8@1+ (1,0) [0|255] "" Vector__XXX
第一行的BO_就代表的是报文,里面有关于报文的信息
1566是十进制的报文ID,DBC里面一般是十六进制的
NM_Wakeup_Message是报文的名称
8是报文长度
ALC是它所属的网络节点
第二行的SG_就是信号,每一段可以有好多行SG_,里面有关于信号在该报文里面的信息
NM_Wakeup_Signal是信号名称
0是起始位
|分隔符
8信号长度多少位
@也是分隔符
1的位置是字节序,0的话是小端,1的话就是大端。
(1,0)代表factor是1,offset是0
[0|255]数值最小0最大255,注意这个是物理值。最大最小值是电机绿框的按钮,根据蓝框里面的数据,计算出来的,只能显示,不能限制数据,也不判断。
""是物理值单位,空的话就是没单位,里面可以是kw %之类的单位
Vector__XXX是接收这条报文的节点名字,没设置的话就显示Vector__XXX,有设置的话就显示节点名字,有多个接收节点就用逗号隔开
信号
一大堆BO_的后面,就是一大堆CM_这就是信号
CM_ SG_ 813 Tbox_ChargeStartTimeMinu "充电开始时间";
CM_ SG_ 813 Tbox_MaxChargeSOCSet "Max
最大充电SOC设置";
CM_代表单条信号,不是在报文里面。
SG_就是报文
813是信号所在报文的ID十进制
Tbox_ChargeStartTimeMinu是信号名字
充电开始时间是信号的comment可以有好多行,在DBC文件里面也是用回车隔开
有时候会有人写的DBC存在未关联报文的信号,DBC工具就会统一放在0xC0000000报文里面
BO_ 3221225472 VECTOR__INDEPENDENT_SIG_MSG: 0 Vector__XXX
SG_ Reserved1 : 0|4@0+ (1,0) [0|15] "" Vector__XXX
SG_ Reserved2 : 0|4@0+ (1,0) [0|15] "" Vector__XXX
……
CM_ BO_ 3221225472 "This is a message for not used signals, created by Vector CANdb++ DBC OLE DB Provider.";
属性
BA_开头就是属性值,跟C语言的#define是一样的。
BA_DEF_ BO_ "GenMsgSendType" ENUM "Cycle","Event","CE";
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0;
BA_DEF_DEF_ "GenMsgSendType" "Cycle";
BA_DEF_DEF_ "GenMsgCycleTime" 0;
BA_ "GenMsgCycleTime" BO_ 863 100;
BA_ "GenMsgCycleTime" BO_ 1300 500;
数值
VAL_也就是每个信号的数值代表什么意思
VAL_ 863 Tbox_ChargeValid 0 "No Req" 1 "Set End Time" 2 "Not Set End Time" 3 "Invalid" ;
863是信号所在报文ID十进制
Tbox_ChargeValid信号名称
后面的就是数值0代表"No Req",数值1代表"Set End Time"……
环境变量
EV_开头的就是环境变量
EV_ New_Variable_1: 0 [0|16] "" 0 1 DUMMY_NODE_VECTOR0 Vector__XXX;
New_Variable_1环境变量的名字
0是类型:0整形1浮点型2字符串
[0|16]最小0最大16
""单位
0初始值
1环境变量ID
DUMMY_NODE_VECTOR0是access_type,0=unrestricted, 1=read, 2=write, 3=readWrit
Vector__XXX所属节点名字
回归问题
回到问题中来,我用记事本打开的时候发现了个什么问题呢?
是真的坑爹,同一条报文里面塞了两个一模一样的信号,还是不同的位置!
所属报文ID还写错了!
同一个信号放到两个不同ID的报文里面!
也是绝了。
问题解决
好在我这次分析不需要用到出问题的信号,把他们删掉就好,大不了少几个信号而已,然后DBC文件就能打开了。
但是打开之后还有好多错误,没眼看。