CANDB++中的CAN_DBC快速编辑方法,使用文本编辑器(如notepad++和VScode)
前言:
在做工程机械CAN协议相关的软件开发与调试时,经常接触到DBC的使用,可以在CAN分析仪中加载DBC文件从而快速查看某条CAN报文或信号的含义,以及使用图形化的调试。
而编辑DBC文件,正常是用CANDB++来一条条添加,比较费时费力。其实可以直接使用文本编辑器打开dbc文件,通过复制粘贴以及修改的方法快速添加报文和信号。
很多文本编辑器都能打开dbc文件,但是比如记事本等是没有关键字高亮显示的功能的,因此最好是用notepad++和VScode,由于我本身就安装了VScode。所以我就用VScode来实现。
VScode需要安装一个插件,在插件搜索栏中输入“DBC”,第一个就是DBC language Syntax,安装即可。实际使用发现能自动高亮,并且某些错误还能自动波浪线提醒。还比较好用。
搜索了一下,目前网上的资料较少,还是自己测试整理后分享给大家吧。
一、创建一个基础的DBC文件。
1)这里还是得用CANDB++,我直接用的1939模板。
2)dbc文件中随意输入1个message和2个信号,并将信号挂在到message中
二、用文本编辑器修改
2.1 vscode打开保存的DBC文件:
VERSION ""NS_ : NS_DESC_CM_BA_DEF_BA_VAL_CAT_DEF_CAT_FILTERBA_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_:BO_ 2364539904 Engin_state: 8 Vector__XXXSG_ Engin_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ Engin_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXXBA_DEF_ BO_ "TpJ1939VarDlc" ENUM "No","Yes";
BA_DEF_ SG_ "SigType" ENUM "Default","Range","RangeSigned","ASCII","Discrete","Control","ReferencePGN","DTC","StringDelimiter","StringLength","StringLengthControl";
BA_DEF_ SG_ "GenSigEVName" STRING ;
BA_DEF_ SG_ "GenSigILSupport" ENUM "No","Yes";
BA_DEF_ SG_ "GenSigSendType" ENUM "Cyclic","OnWrite","OnWriteWithRepetition","OnChange","OnChangeWithRepetition","IfActive","IfActiveWithRepetition","NoSigSendType";
BA_DEF_ BO_ "GenMsgFastOnStart" INT 0 100000;
BA_DEF_ SG_ "GenSigInactiveValue" INT 0 0;
BA_DEF_ BO_ "GenMsgCycleTimeFast" INT 0 3600000;
BA_DEF_ BO_ "GenMsgNrOfRepetition" INT 0 1000000;
BA_DEF_ SG_ "GenSigStartValue" INT 0 2147483647;
BA_DEF_ BO_ "GenMsgDelayTime" INT 0 1000;
BA_DEF_ BO_ "GenMsgILSupport" ENUM "No","Yes";
BA_DEF_ BO_ "GenMsgStartDelayTime" INT 0 100000;
BA_DEF_ BU_ "NodeLayerModules" STRING ;
BA_DEF_ BU_ "ECU" STRING ;
BA_DEF_ BU_ "NmJ1939SystemInstance" INT 0 15;
BA_DEF_ BU_ "NmJ1939System" INT 0 127;
BA_DEF_ BU_ "NmJ1939ManufacturerCode" INT 0 2047;
BA_DEF_ BU_ "NmJ1939IndustryGroup" INT 0 7;
BA_DEF_ BU_ "NmJ1939IdentityNumber" INT 0 2097151;
BA_DEF_ BU_ "NmJ1939FunctionInstance" INT 0 7;
BA_DEF_ BU_ "NmJ1939Function" INT 0 255;
BA_DEF_ BU_ "NmJ1939ECUInstance" INT 0 3;
BA_DEF_ BU_ "NmJ1939AAC" INT 0 1;
BA_DEF_ BU_ "NmStationAddress" INT 0 255;
BA_DEF_ BO_ "GenMsgSendType" ENUM "cyclic","NotUsed","IfActive","NotUsed","NotUsed","NotUsed","NotUsed","NotUsed","noMsgSendType";
BA_DEF_ BO_ "GenMsgRequestable" INT 0 1;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 3600000;
BA_DEF_ SG_ "SPN" INT 0 524287;
BA_DEF_ "DBName" STRING ;
BA_DEF_ "BusType" STRING ;
BA_DEF_ "ProtocolType" STRING ;
BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";
BA_DEF_DEF_ "TpJ1939VarDlc" "No";
BA_DEF_DEF_ "SigType" "Default";
BA_DEF_DEF_ "GenSigEVName" "Env@Nodename_@Signame";
BA_DEF_DEF_ "GenSigILSupport" "Yes";
BA_DEF_DEF_ "GenSigSendType" "NoSigSendType";
BA_DEF_DEF_ "GenMsgFastOnStart" 0;
BA_DEF_DEF_ "GenSigInactiveValue" 0;
BA_DEF_DEF_ "GenMsgCycleTimeFast" 0;
BA_DEF_DEF_ "GenMsgNrOfRepetition" 0;
BA_DEF_DEF_ "GenSigStartValue" 0;
BA_DEF_DEF_ "GenMsgDelayTime" 0;
BA_DEF_DEF_ "GenMsgILSupport" "Yes";
BA_DEF_DEF_ "GenMsgStartDelayTime" 0;
BA_DEF_DEF_ "NodeLayerModules" "";
BA_DEF_DEF_ "ECU" "";
BA_DEF_DEF_ "NmJ1939SystemInstance" 0;
BA_DEF_DEF_ "NmJ1939System" 0;
BA_DEF_DEF_ "NmJ1939ManufacturerCode" 0;
BA_DEF_DEF_ "NmJ1939IndustryGroup" 0;
BA_DEF_DEF_ "NmJ1939IdentityNumber" 0;
BA_DEF_DEF_ "NmJ1939FunctionInstance" 0;
BA_DEF_DEF_ "NmJ1939Function" 0;
BA_DEF_DEF_ "NmJ1939ECUInstance" 0;
BA_DEF_DEF_ "NmJ1939AAC" 0;
BA_DEF_DEF_ "NmStationAddress" 254;
BA_DEF_DEF_ "GenMsgSendType" "noMsgSendType";
BA_DEF_DEF_ "GenMsgRequestable" 1;
BA_DEF_DEF_ "GenMsgCycleTime" 0;
BA_DEF_DEF_ "SPN" 0;
BA_DEF_DEF_ "DBName" "";
BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "ProtocolType" "J1939";
BA_DEF_DEF_ "VFrameFormat" "J1939PG";
BA_ "DBName" "J1939";
BA_ "VFrameFormat" BO_ 2364539904 3;
2.2 其中可以找到跟ID相关的两行文本:
BO_ 2364539904 Engin_state: 8 Vector__XXX
SG_ Engin_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXX
SG_ Engin_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX
BA_ "VFrameFormat" BO_ 2364539904 3;//这行在最后
2.3 message报文格式说明
注意:最后一行(BA_....)中的报文ID与BO_ 这一行的报文ID必须对应,即一个报文对应这两行。
message id的说明:
BO_ <MessageID> <MessageName>: <DLC> <SenderNode>
- 参数说明:
<MessageID>
:消息 ID(10 进制或 16 进制,16 进制需加0x
前缀)。<MessageName>
:消息名称(自定义,如 “Engine_Status”)。<DLC>
:数据长度(Data Length Code,0~8 字节,即 0~8)。<SenderNode>
:发送节点(需在NODE_
中定义过,如 “ECU_Engine”)。
2.4 信号说明
SG_ <SignalName> : <StartBit>|<BitLength>@<ByteOrder><ValueType> (<Factor>,<Offset>) [<Min>|<Max>] "<Unit>" <ReceiverNode>
- 参数说明:
<SignalName>
:信号名称(如 “Engine_Speed”)。<StartBit>
:起始位(消息数据域中的起始位置,0~63,从最低位 0 开始计数)。<BitLength>
:位长度(信号占用的位数,1~64)。<ByteOrder>
:字节序(0
= 小端模式 Little-Endian,1
= 大端模式 Big-Endian)。<ValueType>
:数据类型(+
= 无符号 unsigned,-
= 有符号 signed)。<Factor>,<Offset>
:缩放因子和偏移量(物理值 = 原始值 ×Factor + Offset)。<Min>|<Max>
:物理值范围(可选,如0|8000
表示 0~8000)。<Unit>
:物理单位(可选,如 “rpm”“km/h”)。<ReceiverNode>
:接收节点(多个节点用逗号分隔,如 “ECU_Display,Sensor_Brake”)。
2.5 按照这个格式添加新的报文ID和对应的信号
例如:
.....BO_ 2364539904 Engin_state: 8 Vector__XXXSG_ Engin_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ Engin_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX
BO_ 2364539903 QQ_state: 8 Vector__XXXSG_ QQ_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ QQ_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX......BA_ "VFrameFormat" BO_ 2364539904 3;
BA_ "VFrameFormat" BO_ 2364539903 3;
保存后用CANDB++打开效果:
注意:
最后一行(BA_)最后的3表示报文格式,即行内VFrameFormat对应的枚举:搜索可以查到枚举定义:
BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";
因此,3就表示J1939PG,如果想添加其他格式的报文则需要修改这个,即标准帧为0,这个可以在candb++中添加对应类型的报文来验证:
三、添加注释
3.1 使用//
这种方法只能在编辑器中可以看到,确实可行,但需要注意这种方式做好的DBC文件,如果使用CANDB++再保存一下以后,注释内容会消失掉,因此不推荐
3.2 使用CM_
这种方法不如//直接,只能在所有的报文定义后面写,即BA_DEF_前面紧挨着。
而且只能内容必须与ID、signal、节点等一起。
而且填写的内容会出现在CANDB++的comment中
示例:
BO_ 2364539903 QQ_state: 8 Vector__XXXSG_ QQ_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ QQ_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX//其他的报文定义CM_ BO_ 2565931047 "hhhh";//只能写在这里
BA_DEF_ BO_ "TpJ1939VarDlc" ENUM "No","Yes";