目录
应用场景:
模型实现:
模型数据对象:
模型配置:
模型关联数据对象
生成代码
在开发应用层模型时,有时会使用一些结构体、结构体数组等类型的接口变量,方便与其他C代码进行集成。
那么,我们如何在Simulink模型中实现结构体数组的代码生成呢?
例如我们有以下一个结构体:
typedef struct {
UInt8 Data_Array[8];
BOOL Data_Valid;
UInt8 Data_Length;
} MyStruct;
并定义了两个结构体数组,如下所示:
MyStruct Data_Read[5];
MyStruct Data_Write[5];
现在我们希望Simulink模型实现如下代码的功能:
/* Data_Write功能 */
Data_Write[0].Data_Array[1] = x;
Data_Write[0].Data_Valid = true;
Data_Write[0].Data_Length = 8;
/* Data_Read功能 */
a = Data_Read[1].Data_Array[0];
b = Data_Read[1].Data_Array[0];
c = Data_Read[1].Data_Valid;
d = Data_Read[1].Data_Length;
对于上述功能,我们需要使用Selector 和Assignment这两个模块来实现对数组以及数组结构体的操作。
在Simulink模型中使用Data_Read和Data_Write作为输入输出接口,并在模型中对部分结构体成员做其他逻辑运算处理。模型如下图所示:
结构体类型MyStruct 需要定义成Simulink Bus,可以使用以下脚本方式
% Simulink Bus
MyStruct = Simulink.Bus;
BusElements{1}(1,1) = Simulink.BusElement;
BusElements{1}(1,1).Name = 'Data_Array';
BusElements{1}(1,1).Dimensions = 8;
BusElements{1}(1,1).DataType = 'UInt8';
BusElements{1}(2,1) = Simulink.BusElement;
BusElements{1}(2,1).Name = 'Data_Valid';
BusElements{1}(2,1).Dimensions = 1;
BusElements{1}(2,1).DataType = 'BOOL';
BusElements{1}(3,1) = Simulink.BusElement;
BusElements{1}(3,1).Name = 'Data_Length';
BusElements{1}(3,1).Dimensions = 1;
BusElements{1}(3,1).DataType = 'UInt8';
MyStruct.Elements = BusElements{1};
MyStruct.DataScope = 'Exported';
MyStruct.HeaderFile = 'Var_Struct.h';
Data_Read的数据对象定义
Data_Read = Simulink.Signal;
Data_Read.Dimensions = 5;
Data_Read.DataType = 'Bus: MyStruct';
Data_Read.CoderInfo.StorageClass = 'Custom';
Data_Read.CoderInfo.CustomStorageClass = 'ExportToFile';
Data_Read.CoderInfo.CustomAttributes.HeaderFile = 'Var_Global.h';
Data_Read.CoderInfo.CustomAttributes.DefinitionFile = 'Var_Global.c';
这里为了演示,我们可以再定义两个结构体变量,用于存放上面结构体数组的元素,具体的数据对象定义这里省略
MyStruct Data_Read_Element;
MyStruct Data_Write_Element;
应用场景中的等效代码则可以如下:
Data_Write_Element.Data_Array[1] = x;
Data_Write_Element.Data_Valid = true;
Data_Write_Element.Data_Length = 8;
Data_Write[0] = Data_Write_Element;
Data_Read_Element = Data_Read[1];
a = Data_Read_Element.Data_Array[0];
b = Data_Read_Element.Data_Array[1];
c = Data_Read_Element.Data_Valid;
d = Data_Read_Element.Data_Length;
Data_Read功能部分:
模型中In1端口,需要设置成如下:
指定数据类型为MyStruct
端口维度为5
输出为非虚拟总线
Data_Read 信号线之后的Selector模块设置如下:
Index mode使用‘Zero-based’,即数组下标从0开始
Index Option可以使用Index vector(port),在外部使用Constant指定下标
Input port size 需要指定数组维度(结构体数组维度)
在此Selector之后使用Bus Selector,可以指定需要输出的结构体成员,这里全部输出
后面需要将结构体Data_Read_Element的Data_Array成员(数组)两个元素赋值给a,b变量,这里还需要使用一个Selector模块,设置可以参照上面:
Index Option选择使用Index vector(port)
也可以选择Index vector(dialog),需要在Selector中设置Index部分,如下图:
Data_Write功能部分:
这里需要实现将变量x赋值给某个指定的数组元素的功能,需要使用Assignment模块
模块配置如下:
Index mode:‘Zero-based’,数组下标从0开始
Index Option:选择Index vector(port),数组下标由外部输入,
Initialize output:Specify size for each dimension in table ,同时需要指定Output Size为8
在上面输出一个数组后,需要赋值给结构体Data_Write_Element
使用BusCreator构建一非虚拟总线,BusCreator设置如下:
最后还需要一个Assignment,将上述BusCreator输出的结构体Data_Write_Element 赋值给结构体数组Data_Write[0] ,Assignment设置如下图所示:
以上模型设置基本完成
上面我们使用了Data_Write_Element、Data_Read_Element两个结构体变量作为中间变量,如果不使用这两个中间变量,这两个信号线不做数据对象管理,也是可以实现同样的功能,有兴趣的童鞋可以试一下,看下最终代码的可读性。
如果你觉得本文能够帮助到你,请长按识别下方二维码关注公众号,另有知乎同名专栏同步更新,欢迎分享转载
文章中的示例模型或代码均可联系小编免费获取,若对文章有任何意见或建议,欢迎在文章下方留言,也可进入公众号选择‘联系方式’,加小编微信进行交流