Simulink CAN Pack/Unpack模块的代码生成

星期三, 11 05月 2022
在一些应用场合,我们会直接在应用层Simulink模型中使用CAN Pack和CAN Unpack这两个模块加载DBC文件,进行CAN报文的解析和打包。

例如我们有DBC文件,主要包含以下两个报文:

图1.dbc文件Layout

 

现在需要在Simulink中创建MCU的CAN报文处理功能模块,即获取HCU发送的数据,解析获取HCU的指令信号;打包MCU内部信号,作为MCU发送报文。今天就跟大家介绍下CAN Unpack/Pack两种常用的应用场景

应用场景一:定义CAN_Msg_In、CAN_Msg_Out两变量,分别作为输入和输出报文变量

CAN_Msg_In和CAN_Msg_Out都为CAN_MESSAGE 类型。

 

在与底层驱动进行集成时,底层可使用CAN_Msg_In和CAN_Msg_Out这两个变量,或再定义其他CAN_MESSAGE 类型的接口变量。

 

图2.CAN Unpack/Pack建模

上述CAN_MESSAGE数据类型在MATLAB自带的can_message.h中进行了定义

can_message.h可在MATLAB安装路径下找到一个文件,如下图。可以将此文件拷贝至当前路径下

图3.can_message.h所在路径

图4.CAN_MESSAGE结构体

知道了CAN_MESSAGE 类型的定义后,这两个模块的使用就很简单了,我们可以在工作区定义名为CAN_MESSAGE的Simulink Bus数据对象,如下:

图5.定义CAN_MESSAGE Simulink.Bus数据对象

再定义CAN_Msg_In和CAN_Msg_Out两个Simulink.Signal数据对象,数据类型选择上面定义好的 Bus:CAN_MESSAGE

图6.CAN_Msg_In Simulink.Signal数据对象

其他信号的数据对象都是基础数据类型(double,unit8,int16等),这里不再赘述,所有数据对象最终定义成如下:

图7.所有数据对象

信号线关联数据对象,仿真无误,生成代码如下:

图8.变量定义

 

CAN Unpack部分代码,使用CAN_Msg_In变量直接进行解析

图9.CAN Unpack模块部分代码

CAN Pack部分代码,信号打包输出CAN_Msg_Out

图10.CAN Pack模块部分代码

 

应用场景二:对于底层驱动已经定义了CAN_MsgIn_Data[8] CAN_MsgOut_Data[8] 两个数组变量作为接口,用于存放CAN报文的Data部分,应用层只能使用这两个数组,此时可用这种方法。此方法其实和场景一种的很相似,都需要使用CAN_MESSAGE这个数据类型。首先也需要在工作区(或数据字典)中定义CAN_MESSAGE Simulink.Bus数据对象。

与场景一的主要区别是CAN Pack中需要勾选 Output as bus

图11.CAN Pack模块设置

此时,在CAN Pack输出端可接一个Bus Selector,仅输出Data

图12.Bus Selector选择Data部分输出

而CAN Unpack输入端,需要我们自己构造一个Bus信号,且需勾选输出为非虚拟总线,输出类型选择定义好的Bus:CAN_MESSAGE

图13.Bus Creator构造非虚拟总线

其他设置与应用场景一类似,这里为了演示函数封装,将CAN UnPack/Pack都封装在单独的原子子系统中,并设置相应的函数和文件名。生成的部分代码如下:

图13.生成的step函数


 

Tips:需要注意的是,应用场景二中需要设置CAN pack模块输出bus信号,而稍低版本的MATLAB(例如16b)中是没有此项设置的

 

如果是这种情况,可在CAN Pack后面再增加一个CAN Unpack模块,并选择raw data输出

 

这种方法最后输出的直接是数组了,但因为多了一个CAN Unpack,无形中引入了该部分的代码,而该部分代码中涉及memcpy这个C库函数,这里也需要注意一下

 

 

除了这两个应用场景之外,在命令行输入canMessageBusType,工作区会自动创建一个名为CAN_MESSAGE_BUS的Simulink Bus数据对象,用法和上面我们自定义的CAN_MESSAGESimulink Bus数据对象类似,感兴趣的童鞋可以尝试一下。

3127 次