MBD之代码生成——结构体数组的生成

 

目录

应用场景:

模型实现:

模型数据对象:

模型配置:

模型关联数据对象

生成代码


在开发应用层模型时,有时会使用一些结构体、结构体数组等类型的接口变量,方便与其他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_ReadData_Write作为输入输出接口,并在模型中对部分结构体成员做其他逻辑运算处理。模型如下图所示:

MBD之代码生成——结构体数组的生成_第1张图片

 

 

 

模型数据对象:

结构体类型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

  • 输出为非虚拟总线

MBD之代码生成——结构体数组的生成_第2张图片

Data_Read 信号线之后的Selector模块设置如下:

  • Index mode使用‘Zero-based’,即数组下标从0开始

  • Index Option可以使用Index vector(port),在外部使用Constant指定下标

  • Input port size 需要指定数组维度(结构体数组维度)

MBD之代码生成——结构体数组的生成_第3张图片

 

在此Selector之后使用Bus Selector,可以指定需要输出的结构体成员,这里全部输出

 

后面需要将结构体Data_Read_ElementData_Array成员(数组)两个元素赋值给a,b变量,这里还需要使用一个Selector模块,设置可以参照上面:

  • Index Option选择使用Index vector(port)

  • 也可以选择Index vector(dialog),需要在Selector中设置Index部分,如下图:

MBD之代码生成——结构体数组的生成_第4张图片

 

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

MBD之代码生成——结构体数组的生成_第5张图片

 

在上面输出一个数组后,需要赋值给结构体Data_Write_Element

使用BusCreator构建一非虚拟总线,BusCreator设置如下:

MBD之代码生成——结构体数组的生成_第6张图片

 

最后还需要一个Assignment,将上述BusCreator输出的结构体Data_Write_Element 赋值给结构体数组Data_Write[0]Assignment设置如下图所示:

MBD之代码生成——结构体数组的生成_第7张图片

以上模型设置基本完成

 

模型关联数据对象

MBD之代码生成——结构体数组的生成_第8张图片

生成代码

MBD之代码生成——结构体数组的生成_第9张图片


    上面我们使用了Data_Write_Element、Data_Read_Element两个结构体变量作为中间变量,如果不使用这两个中间变量,这两个信号线不做数据对象管理,也是可以实现同样的功能,有兴趣的童鞋可以试一下,看下最终代码的可读性。

 

如果你觉得本文能够帮助到你,请长按识别下方二维码关注公众号,另有知乎同名专栏同步更新,欢迎分享转载

文章中的示例模型或代码均可联系小编免费获取,若对文章有任何意见或建议,欢迎在文章下方留言,也可进入公众号选择‘联系方式’,加小编微信进行交流

                                                             

你可能感兴趣的:(MBD)