本文研究通过Matlab函数导入DBC文件的方法,并根据博主自己的工作经验描述DBC文件中的属性信息。
文章目录
- 1 问题引入
- 2 导入DBC示例
- 3 DBC中的一些注意点
- 3.1 节点(Nodes)
- 3.2 帧(Messages)
- 3.2.1 帧ID
- 3.2.2 标准帧和扩展帧
- 3.2.3 DLC
- 3.3 信号(Signals)
- 3.3.1 startbit & length属性
- 3.3.2 factor & offset属性
- 3.3.3 Value Type属性
- 3.3.4 Byte Order属性
- 4 总结
1 问题引入
在博主以前的一篇博客《通过正则表达式解析DBC文件》中,尝试通过Matlab的正则表达式函数来解析出DBC文件中的帧、信号信息。由于DBC的文本具有一定规律,这种方法从理论上来说是可行的。但是在实际工作中需要花费大量的时间去开发、维护Matlab脚本,另外使用正则表达式解析大的DBC文件会耗费很久的时间。
最近博主发现,Mathworks公司已经很“贴心地”帮我们做好了解析DBC文件的封装函数,不用我们自己造轮子了。只要购买了Vehicle Network Toolbox这个工具箱,就可以调用下面的函数来解析DBC文件。
db = canDatabase('filename.dbc')
2 导入DBC示例
在Matlab命令行输入以下命令,就可以导入Matlab自带的一个示例DBC文件的信息。
cd ([matlabroot '\examples\vnt'])
d = canDatabase('demoVNT_CANdbFiles.dbc');
在命令行输入d并回车,返回一下导入的变量d里面包含了什么。
d =
Database - 属性:
Name: 'demoVNT_CANdbFiles'
Path: 'C:\Program Files\MATLAB\R2018a\examples\vnt\demoVNT_CANdbFiles.dbc'
Nodes: {}
NodeInfo: [0×0 struct]
Messages: {5×1 cell}
MessageInfo: [5×1 struct]
Attributes: {}
AttributeInfo: [0×0 struct]
UserData: []
返回的变量d中包含了这个DBC的文件名、节点、帧等信息。可以看出这个示例DBC文件中缺少了节点(Nodes)信息,但是有5个报文帧(Messages)。注意到,变量中包含一个MessageInfo属性,其中包含了更多的帧属性信息以及每一帧里面每一个信号的详细信息。这些都可以通过命令行返回,也就是说可以在脚本中随意地调用。
3 DBC中的一些注意点
网上关于DBC文件的文章有很多了,博主也不再讲DBC中的各种细节,而是谈谈工作中遇到的一些问题,和一些注意点。作为汽车ECU软件开发工程师,一般是会拿到电器架构部门的工程师提供的DBC文件,而不是自己创建DBC。收到DBC文件后,一般会关注3个东西,节点(Nodes)、帧(Messages)和信号(Signals)。
3.1 节点(Nodes)
在CANdb++ Editor左边的浏览器中点击Network Nodes,可以看到DBC文件中所有的节点。
作为软件开发工程师,需要关注自己团队开发的ECU对应的节点。譬如博主关注的是Controller这个节点,打开这个节点就可以知道这个节点的发送帧(TX)和接收帧(RX)。
了解了哪些发送帧和接收帧以后,就需要关注具体每一帧的内容。
3.2 帧(Messages)
关于DBC中的帧,博主因为概念不了解,犯过很多错误。
3.2.1 帧ID
在CANdb++ Editor中看到的帧ID号是16进制的,例如下图的elbowPitchAngleMessage,其ID号是0x23。
但是用文本编辑器(如Notepad++)打开DBC,其ID号就是10进制的,这点要注意区分。
3.2.2 标准帧和扩展帧
在CANdb++ Editor中双击某一个帧,就可以从Type属性看出它是标准帧还是扩展帧。
在标题中,可以看出帧ID号0x51x末尾有一个x,这也说明它是一个扩展帧。
3.2.3 DLC
帧里面有一个属性叫做DLC,全称是Data Length Code,代表了这一帧有多少个Byte。一般来说,DLC都是8,也就是说每一帧都有8个byte。
我们都知道1个byte等于8个bit,8个byte就是64个bit。切换到Layout窗口,可以看到这一帧的布局,里面有64个格子就不难理解了。
3.3 信号(Signals)
在帧里面会有很多信号,根据一定的规则排布在帧里面。博主在另一篇博客《Simulink代码生成:CAN Pack模块及其代码》中通过仿真研究了信号打包进在帧里的方式。
3.3.1 startbit & length属性
startbit & length属性指的是起始位和长度。如下图所示,起始位是0,长度是64,表示占了64个bit。
在Message的Layout中就可以看到这个信号占满了所有的bit。
3.3.2 factor & offset属性
信号从物理值,经常需要进行大小的缩放和偏移,才能转换成逻辑值,打包到Message中。
物理值和逻辑值是博主和同事习惯的叫法。物理值是指软件应用层参与策略计算的值,具有实实在在的物理意义;逻辑值是指在CAN中发送的值,也就是物理值通过factor&offset转换过后的值。两者之间的关系如下:
raw_value = (physical_value - Offset) / Factor
如果不做转换,那么factor&offset分别是1和0.
3.3.3 Value Type属性
Value Type属性表示打包进Message的时候的类型选择。博主在工作中只遇到过Unsigned和Signed两种Value Type属性,而且一般来说Unsigned较多。
Value Type属性也有一套转换机制,具体可以参照博主另一篇博客《Simulink代码生成:CAN Pack模块及其代码》中的仿真过程。
3.3.4 Byte Order属性
Btye Order属性表示打包Message时的字节顺序,分为Intel和Motorola两种。当一个Signal跨越多行的时候,Byte Order属性就会决定打包时候的顺序,具体区别如下:
- Intel格式:Signal的低位存放在Message的低位,Signal的高位存放在Message的高位。
- Motorola格式:Signal的低位存放在Message的高位,Signal的高位存放在Message的低位。
研究Byte Order属性要和Message Layout一起看,可以参照博主另一篇博客《Simulink代码生成:CAN Pack模块及其代码》中的仿真。
4 总结
通过Matlab导入DBC文件的方法并不难,主要就是一个简单的函数和Matlab结构体的运用。主要是在实践过程中理解DBC文件。
相关博客:
《Matlab编程技巧:通过正则表达式解析DBC文件》《Simulink代码生成:CAN Pack模块及其代码》