代码生成器功能
生成的代码中的内部函数
*Engee*代码生成器支持*虚拟*和*原子*子系统进行代码生成。 虚拟子系统仅为模型中的可视层次结构服务,而原子子系统表示单个执行单元(或生成代码中的函数)。 子系统属性中的设置"视为原子单元"允许您使子系统虚拟或原子。 *Virtual*子系统内的所有计算都直接嵌入(内联)到封闭子系统或模型的代码中。 这可以提高生成代码的性能,但会降低模型的可读性和可追溯性。 *Atomic*子系统中的所有计算都是在一个单独的函数中生成的,该函数具有子系统名称。 然后在底层子系统或模型的代码中自动调用此函数。 这可以提高生成的代码对模型的可读性和可追溯性,但会降低性能。
例如,将`RollMode`从`autopilot_roll转换。工程师模型(见 代码生成示例)到原子子系统:
保存模型并再次生成代码。 生成的代码现在有一个名为`RollMode’的函数(对应于模型中的子系统名称)。 此函数在`autopilot_roll_step`函数内部调用,该函数表示封闭模型的代码。 'RollMode’函数被声明为’static',因此是该模型的内部函数。
代码生成器会忽略禁用的块,并且不会创建关联的代码。 |
生成的代码中的参数
模型块中的参数
在模型块中,可以设置参数:
-
以数字的形式(例如’0.2'`;
-
以表达式的形式(例如,
0.2+0.7
); -
以来自*Engee*工作区的变量名称的形式(例如’Kp'`。
在生成的代码中,参数与模型中指定的值嵌入(内联)。:
-
简单的数值"按原样"添加到代码中,不需要额外的操作。;
-
表达式可以简化,代码中只会出现最终的计算值。;
可配置参数
一些块参数可以被设置为可配置的(tunable),以便在代码生成后可以更改它们。 这样的参数存储在’modelname_P’结构中,如下所示:
-如果使用变量名称(例如,Kp
)设置参数,则其名称存储在结构中。:
+
struct P_modelname_T_ {
double Kp;
};
-如果参数设置为表达式(例如’Kp+1`),则使用参数名称(例如,'Amplitude`):
+
struct P_modelname_T_ {
double Amplitude;
};
在所有情况下,'modelname_P’结构中的参数都用模型中可用的计算值填充,例如:
P_modelname_T modelname_P = {
0.5//参数值
};
使用选项 参数的默认行为 在 设置窗口
|
生成的代码的接口和集成到外部开发环境
生成代码的接口
生成的代码的外部接口可以在生成的文件"modelname"中看到。h'。 外部接口包括用于处理生成的代码的函数和结构。:
-
'modelname_init—-是模型的初始化函数-必须调用一次;
-
'modelname_step’是模型的入口点,包含模型的算法。 它应该按照计算模型的步骤定期调用;
-
'modelname_U—-结构包含模型的外部输入端口;
-
'modelname_Y—-结构包含模型的外部输出端口;
-
'modelname_S—-结构包含模型的内部状态;
-
'modelname_P—-结构包含可配置的模型参数。
集成到外部开发环境中
使用生成的"modelname"文件的函数和结构。h’在外部代码(手动编写)中,您需要执行以下操作:
-
附加生成的头文件:
#include "modelname.h"
-
在您的`main`中组织对生成的`init`函数的单个调用:
modelname_init();
-
组织一个定期调用生成的"步骤"函数在您的"主"与所需的步骤:
modelname_step();
-
组织输入和输出数据与"步骤"函数之间的传输:
/* 设置输入的值 */ modelname_U.input1 = 42; /* 调用step函数 */ modelname_step(); /* 您可以使用modelname_Y.output1 */
生成的文件
在*Engee*中构建模型并生成其代码后(使用’engee’命令。generate_code`)'或按钮 生成代码 )自动生成的文件被创建,其中包含c语言中模型的实现。 下面是这些文件及其用途的描述。
-
'modelname。h’是描述模型外部接口的头文件。 它包括从外部代码使用模型所需的函数和结构(有关详细信息,请参阅 上)。 部分中还描述了将这些函数和结构连接到外部应用程序的过程 上。
-
'modelname。c’是具有模型逻辑实现的文件。 它包含所有变量的定义和模型关键功能的实现。:
-
'init()'是一个初始化函数,用于设置变量和模型状态的初始值`;
-
'step()'是主要的计算函数。 执行一个仿真步骤的计算并更新输出值;
-
'term()'是模型的关断函数。
-
-
'model_data。c’是模型参数初始初始化的文件。 它设置执行模型时使用的所有可配置参数的值。 例如:
-
信号幅度和频率;
-
相位,偏移;
-
样数等参数。
这些全局参数是可配置的,并且可以在可执行代码运行时更改。 这使您可以灵活地控制模型的行为,而无需重新组装逻辑或编辑主要功能。
-
-
""主啊。c’是一个带有使用模型示例的文件。 这是演示如何从C程序初始化和调用模型的主要可执行文件。 包含:
-
'init()'是模型的初始化函数,在开始工作之前调用一次。;
-
'step()'是执行计算模型的一个步骤的主要计算函数。 它通常被称为定期,根据指定的积分步骤。;
-
'term()'是模型的关断函数。
的’主。c’文件不包含模型的算法,而只是演示了如何在具有C代码支持的应用程序中正确启动和管理其执行。 ""主啊。c’应用作将模型集成到用户项目中的模板。
-
支持的数据类型
生成的代码中的数据类型与*Engee*模型中的数据类型相对应。
如果用户没有在模型中指定数据类型,则使用与C中的`double`类型对应的双精度浮点数据类型。 对于生成布尔结果(true(1)`或`false(0)
)的逻辑运算或计算,使用布尔数据类型,对应于C中的八位无符号数据类型。
要在模型中显示数据类型,请在 设置窗口 ![]() |
多频型号
*Engee*模型可以是多频率的,即它们包含几种不同的采样率。 应用区块 速率转变 通过设置块和子系统的"采样时间"参数,用户可以控制计算步骤块或块组的工作。
Engee代码生成器支持多频模型的代码生成。 为此,块按频率分组,并且用户可以控制这些不同频率在生成的代码中如何表示。
定制化 多频代码生成 允许您控制多频率模型的生成代码的操作模式。 "单任务"代码允许您为模型生成单个"步骤"函数。 "多任务"代码允许您为模型生成几个"步骤"函数,每个函数对应于模型中的特定采样率。
*单任务代码*在生成的`step`函数中包含条件(以’if`的形式),该函数将调用包装到模型中较慢的频率。 "步骤"功能包含以模型的基本频率(最快频率)操作的块。 从用户线束提供对`step`函数的调用就足够了,同时调度对较慢频率的调用以及频率之间的信息交换在生成的代码本身中自动进行。
*多任务代码*在生成的代码中包含几个`step_N`函数,每个函数都与其在模型中的频率相对应。 函数’step_0’对应于模型中最快的频率(基础频率),函数`step_1`对应于第二个较慢的频率,依此类推。 从自定义绑定中,需要提供对`step_N`函数的调用以及必要的计算步骤。 在生成的代码本身中自动提供不同频率之间的数据交互。
代码验证
验证是指用块生成验证模型 C 功能,其仿真结果必须与具有相同输入数据的原始模型的仿真结果相匹配。
座 C 功能 它可以自动创建以验证生成的代码。 为此,请选中此框 生成 C 功能块 在设置窗口中 :
下次生成代码时(通过界面、上下文菜单或命令 generate_code)文件’modelname_verification。jl’将出现在目录’ouput_dir`中(如果目录不存在,它将自动创建)。 此文件将包含一个可以在脚本编辑器中执行的脚本(通过双击) 或命令行
:
include("path/to/verification.jl")
该脚本将创建一个名称为"modelname_verification"的Engee模型。恩吉和一个街区 C 功能,其中使用生成的代码:
Verilog语言的代码生成也可在*Engee*中使用。 有关详细信息,请参阅文章 Verilog(HDL)代码生成.
基于自定义模板的代码生成
*Engee*支持基于自定义模板的代码生成(有关更多信息,请参阅文章 根据自定义模板生成代码).
管理信号名称
代码生成器使用模型中用户指定的信号的名称,使生成的代码更清晰,更容易与模型匹配。 例如:
如果信号(块输出)具有名称,那么生成的代码将为此信号使用相同的变量名称。 这只有在信号未被优化并且不包含C代码中不支持的字符时才可能。