使用符号维度生成代码以实现灵活的信号大小
Simulink® 中的符号维度代表模型中的信号维度。在构建模型时,您不使用固定的值来表示维度,而是使用符号。无论何时需要指定信号维度(例如模块和数据对象),都可以使用符号维度而不是值。
对于具有符号维度的模型,Simulink 会在整个图中传播符号维度。当您使用 Embedded Coder® 生成代码时,生成的代码会在预处理器条件中包含符号维度,这使得代码灵活并且能够处理不同的维度,而无需重新生成代码。有关创建具有符号维度的模型的更多信息,请参阅Create a Model with Symbolic Dimensions。
符号维度的存储类别
要实现符号维度,请在基础工作区或数据字典中创建一个表示符号维度的 Simulink.Parameter
对象。为了成功生成代码,Simulink.Parameter
对象必须具有以下存储类之一:
Define, ImportedDefine
指定了头文件用户定义的自定义存储类,将数据定义为指定头文件中的宏
对于具有 ImportedDefine
自定义存储类的 Simulink.Parameter
对象,请确保头文件位于 MATLAB 路径上。在 Simulink.Parameter
对话框中的 HeaderFile 框中输入头文件的名称。
有关更多信息,请参阅Choose Storage Class for Controlling Data Representation in Generated Code。
生成具有符号维度的 C 代码
在为具有符号维度的模型生成代码之前,请确保仿真成功。Simulink 模块处理符号维度的能力各不相同。有些模块可以处理符号维度,而其他块则会产生错误。只要不受支持的模块不与符号维度交互,它们仍然可以在包含符号维度的模型中工作。
提示
要识别支持符号维度功能的 Simulink 模块,请在 MATLAB 命令提示符中输入 showblockdatatypetable
并检查模块支持表。
设计模型
在此示例中,您将输入端口和输出端口模块信号的信号维度定义为符号维度。
定义符号维度
在基础工作区中创建一个
Simulink.Parameter
对象S
。S = Simulink.Parameter;
使用
Value
字段将S
的信号维度大小设置为 3,并将数据类型设置为double
。S.Value = 3; S.DataType = "double";
打开输入端口模块
In1
的模块参数对话框。默认情况下,端口维度参数设置为-1
,表示端口从连接的信号继承维度。使用符号维度S
设置端口维度参数。类似地,将In2
、In3
、Out1
中的端口维度改为S
。在调试选项卡的诊断部分中,选择叠加信息 > 信号维度。
仿真模型。观察一下 Simulink 在整个图表中传播符号维度。
生成代码
要为此模型生成代码,请打开 Embedded Coder。
在代码映射编辑器中,在参数选项卡下,将
S
的存储类设置为CompilerFlag
。有关详细信息,请参阅Storage Class Properties。从 Embedded Coder 构建代码时指定符号维度。在配置参数对话框的代码生成 > 自定义代码窗格中,选择代码信息选项选项卡,并在定义框中输入
S=3
。点击确定。请参阅代码生成窗格:自定义代码:附加构建信息:定义 。在 C 代码选项卡上,点击构建。
代码生成器在您当前的工作文件夹中创建文件夹
model_name_ert_rtw
并将源代码文件放在该文件夹中。查看生成的代码。在
model_name.h
中,为输入端口和输出端口模块定义了符号维度。typedef struct { real_T In1[S]; /* '<Root>/In1' */ real_T In2[S]; /* '<Root>/In2' */ real_T In3[S]; /* '<Root>/In3' */ } ExtU_slexVariantDimension_T; typedef struct { real_T Out1[S]; /* '<Root>/Out1' */ } ExtY_slexVariantDimension_T;
输入端口和输出端口模块的数组大小由符号维度大小
S
定义。在
model_name.c
中,循环边界计算中使用符号维度。void slexVariantDimension_step(void) { int32_T i; for (i = 0; i < S; i++) { slexVariantDimension_Y.Out1[i] = (2.0 * slexVariantDimension_U.In1[i] + 3.0 * slexVariantDimension_U.In2[i]) + slexVariantDimension_U.In3[i]; }