生成Nonvirtual子系统的模块化的功能代码
关于Nonvirtual子系统代码生成
默认情况下,当生产nonvirtual子系统的代码,代码生成器的地方内部数据与nonvirtual关联子系统在同一数据结构作为母公司内部数据模型。这可能很难跟踪和测试代码,特别是对于那种一次性子系统。另外,在大型模型包含nonvirtual子系统,数据结构可以成为大编译和潜在的困难。
生成nonvirtual子系统的模块化的功能代码,包括原子子系统和有条件地执行子系统,子系统使用块参数函数与单独的数据。这个块参数指示代码生成器产生一块I / O和DWork nonvirtual子系统功能,数据结构是独立于母公司模型的数据结构。因此,对子系统生成的代码:
更容易跟踪。
更容易测试。
降低了模型的全局数据结构的大小。
使用函数与单独的数据参数,
配置模型与一个ERT-based系统目标文件。
配置子系统原子或有条件地执行。
块参数设置子系统函数包装来
那种一次性的功能
。
配置子系统生成模块功能代码,调用子系统参数对话框,使一系列的选择来显示和启用函数与单独的数据选择。看到配置子系统生成模块功能代码和为Nonvirtual子系统模块化的功能代码获取详细信息。对于应用的局限性,明白了Nonvirtual子系统模块化函数代码的限制。
对原子子系统生成代码的更多信息,见生成子系统的代码作为单独的函数和文件和为各个子系统生成的代码和可执行文件。
配置子系统生成模块功能代码
确认包含子系统的模型使用一个ERT-based系统目标文件。
选择您想要的子系统生成模块功能代码和打开子系统参数对话框。一个原子子系统如下所示的对话框。(在对话框中有条件地执行子系统,对话框选项治疗作为原子单元是灰色的,你可以跳过步骤3)。
如果块参数治疗作为原子单元可以选择但不选择,子系统既不是原子,也不是有条件地执行。选择的参数治疗作为原子单元,这使函数包装的参数代码生成选项卡。选择代码生成选项卡。
为函数包装参数,选择
那种一次性的功能
。在你做出这个选择,函数与单独的数据显示参数。在你为的nonvirtual子系统生成的代码函数与单独的数据参数选择,考虑与参数生成函数代码清除并保存生成的函数
。c
和。h
一个单独的目录中的文件,以便稍后进行比较。选择函数与单独的数据参数。额外的参数出现。
控制子系统功能和生成子系统的命名文件,修改子系统参数函数名的选择和文件名称选项。
保存您的子系统参数变化和通过点击退出对话框好吧。
生成代码的子系统和检查生成的文件,包括功能
。c
和。h
根据您的子系统参数文件命名规范。
对nonvirtual子系统生成代码的更多信息,参见生成子系统的代码作为单独的函数和文件。对于生成子系统功能的代码示例,请参阅为Nonvirtual子系统模块化的功能代码。
为Nonvirtual子系统模块化的功能代码
这个例子展示了如何生成nonvirtual子系统功能代码函数与单独的数据参数清除并选择和比较结果。
打开示例模型
rtwdemo_atomic
。然后,打开嵌入式编码器应用程序,更改系统目标文件ert.tlc
。这个模型显示了如何保护虚拟子系统的边界。当您选择子系统块参数治疗作为原子单元代码生成器生成的代码,执行子系统作为一个原子单元。当配置为原子,您可以指定如何通过设置代码生成器代表子系统函数包装的参数代码生成选项卡。您可以指定子系统是翻译其中一个类型的实现:
内联
:内联子系统代码在调用网站。函数
:空/空
函数与I / O和内部数据模型中全局数据结构。可重用的功能
:可重入函数作为函数参数传递数据。汽车
:代码生成器优化实现基于上下文。
双击魔法石,第1章子系统和检查内容。
然后,关闭子系统窗口。
右键单击魔法石,第1章子系统,从上下文菜单中选择块参数(子系统),并检查设置。金宝app动态仿真模块®和代码生成器可以避免“人工”代数循环时子系统与子系统原子参数最小化代数循环出现。
创建一个变体的
rtwdemo_atomic
显示函数代码没有数据分离。在子系统参数对话框,
在主要选项卡上,选择治疗作为原子单元。
在代码生成标签:
集函数包装来
那种一次性的功能
。集函数名的选择来
用户指定的
。集函数名来
myfun
。集文件名称选项来
使用函数名
。这个设置是可选的,但后来简化了任务的代码比较导致原子子系统功能代码生成文件myfun.c
和myfun.h
。
做不选择函数与单独的数据参数。
点击应用应用更改,然后单击好吧退出对话框。
保存模型变体与一个独特的文件名(例如,
rtwdemo_atomic1
)可写的位置。
创建一个变体的
rtwdemo_atomic
显示函数代码与数据分离。开放模式
rtwdemo_atomic
。打开嵌入式编码器应用程序,更改系统目标文件
ert.tlc
。模型中的画布,右键单击魔法石,第1章子系统和选择块参数(子系统)。在子系统参数对话框,
在主要选项卡上,选择治疗作为原子单元。
在代码生成标签:
集函数包装来
那种一次性的功能
。集函数名的选择来
用户指定的
。集函数名来
myfun
。集文件名称选项来
使用函数名
。选择函数与单独的数据。
点击应用应用变化和点击好吧退出对话框。
保存模型变体与一个独特的文件名(例如,
rtwdemo_atomic2
)可写的位置。
为每个模型生成代码(例如,
rtwdemo_atomic1
和rtwdemo_atomic2
)。比较
/模型
。c。h
和myfun.c
/。h
文件生成的两个模型。代码比较讨论,请参阅H文件差异Nonvirtual子系统功能数据分离和C文件差异Nonvirtual子系统功能数据分离。在本例中,生成的变体中没有显著差异
ert_main.c
,
,模型
_private.h
,或模型
_types.hrtwtypes.h
。
H文件差异Nonvirtual子系统功能数据分离
选择函数与单独的数据原因代码生成器将为子系统中的数据类型定义
myfun.h
文件rtwdemo_atomic2
:/ *块状态(默认存储)系统的< Root > /魔法石,第1章* / typedef struct {real_T Integrator_DSTATE;/ * < S1 > /集成商的* /}DW_myfun_T;
为
rtwdemo_atomic1
,定义子系统数据类型属于模型和出现在rtwdemo_atomic1.h
:/ *块信号(默认存储)* / typedef struct {real_T总和;/ * < Root > /笔的* /}B_rtwdemo_atomic_1_T;/ *块状态(默认存储)系统的<根> * / typedef struct {real_T Integrator_DSTATE;/ * < S1 > /集成商的* /}DW_rtwdemo_atomic_1_T;
选择函数与单独的数据生成以下外部声明的
myfun.h
文件rtwdemo_atomic2
:/ * Extern声明的内部数据系统的< Root > /魔法石,第1章* /走读生DW_myfun_T myfun_DW;外面的空白myfun_Update(无效);走读生空白myfun(无效);
相比之下,生成的代码
rtwdemo_atomic1
包含子系统的模型级外部声明BlockIO
和D_Work
数据,在rtwdemo_atomic1.h
:/ *块信号(默认存储)* /走读生B_rtwdemo_atomic_1_T rtwdemo_atomic_1_B;/ *块状态(默认存储)* /走读生DW_rtwdemo_atomic_1_T rtwdemo_atomic_1_DW;
C文件差异Nonvirtual子系统功能数据分离
选择函数与单独的数据使一个独立的子系统初始化函数,
myfun_initialize
中生成myfun.c
文件rtwdemo_atomic2
:空白myfun_initialize (void) {{((real_T *) &rtwdemo_atomic2_myfunB.Integrator) [0] = 0.0;}rtwdemo_atomic2_myfunDW。Integrator_DSTATE = 0.0;}
子系统初始化函数
myfun.c
模型初始化函数调用的rtwdemo_atomic2.c
:/ *模型初始化函数* /空白rtwdemo_atomic2_initialize (void) {…/ *初始化系统数据* / myfun_initialize ();}
相比之下,
rtwdemo_atomic1
、子系统模型初始化函数初始化的数据rtwdemo_atomic1.c
:/ *模型初始化函数* /空白rtwdemo_atomic1_initialize (void) {…* / / *块I / O {…((real_T *) &rtwdemo_atomic1_B.Integrator) [0] = 0.0;}/ *国家(dwork) * / rtwdemo_atomic1_DWork。Integrator_DSTATE = 0.0;…}
选择函数与单独的数据在生成以下声明
myfun.c
文件rtwdemo_atomic2
:/ *声明变量的内部数据系统的< Root > /魔法石,第1章* / DW_myfun_T myfun_DW;
相比之下,生成的代码
rtwdemo_atomic1
包含的子系统的模型级声明BlockIO
和D_Work
数据,在rtwdemo_atomic1.c
:/ *块信号(默认存储)* / B_rtwdemo_atomic_1_T rtwdemo_atomic_1_B;/ *块状态(默认存储)* / DW_rtwdemo_atomic_1_T rtwdemo_atomic_1_DW;
选择函数与单独的数据生成标识符命名反映子系统数据项的取向。引用子系统数据子系统功能,如
myfun
和myfun_update
在模型中
函数。例如,比较这段代码模型
_stepmyfun
为rtwdemo_atomic2
/ * DiscreteIntegrator:“< S1 > /集成商”* / rtwdemo_atomic_2_Y。着干活= myfun_DW.Integrator_DSTATE;
对应的代码
myfun
为rtwdemo_atomic1
。/ * DiscreteIntegrator:“< S1 > /集成商”* / rtwdemo_atomic_1_Y。着干活= rtwdemo_atomic_1_DW.Integrator_DSTATE;
配分函数生成的代码
这个例子展示了如何将子系统模型中与函数名和文件。
学习如何:
在生成的代码中指定的功能和文件名称。
确定所需的部分生成的代码集成。
为原子子系统生成的代码。
确定所需数据执行生成的功能。
对于信息的示例模型和其他的例子在这个系列中,看到的准备一个控制算法模型C代码生成。
原子和虚拟子系统
模型的例子准备一个控制算法模型C代码生成和配置数据接口在生成的代码中使用虚拟子系统。虚拟视觉子系统组织块但不影响模型的功能。原子子系统评估模块包含在模型作为一个单元。与原子子系统,可以指定额外的功能分区信息。在一个模型中,原子子系统出现了一个大胆的边界。
视图的变化模型架构
打开示例模型rtwdemo_PCG_Eval_P3。
将模型的副本保存到一个可写的文件夹。
这个例子展示了如何将虚拟子系统替换为函数调用子系统。函数调用子系统:
都是原子的子系统
使您能够控制子系统执行顺序
执行时函数调用信号触发器
通过控制子系统的执行顺序,您可以匹配模型与现有系统特定的执行顺序。
函数调用图识别子系统(1)PI_ctrl_1
,PI_ctrl_2
,Pos_Command_Arbitration
。
这个版本的模型包含新的子系统Execution_Order_Control
(2),其中包含一个Stateflow®图表,模型调用调度程序的功能。子系统控制函数的执行顺序调用子系统通过函数调用(3)的信号。在这个例子中,你如何改变执行顺序可以改变仿真结果。
这个版本的模型包含新的信号转换模块(4)输出的PI控制器。有了这些额外的块,代码生成器可以生成一个可重入函数的PI控制器。
控制功能位置和文件放置在生成的代码中
在准备一个控制算法模型C代码生成和配置数据接口在生成的代码中,代码生成器创建一个模型
_step
包含控制算法代码的函数。然而,许多应用程序需要更大程度的控制函数的文件位置。通过修改原子子系统的参数,您可以指定多个函数在单个模型。
图中显示子系统参数PI_ctrl_1
。
治疗作为原子单元
使其他子菜单。原子子系统,该参数自动选择和残疾人。
样品时间
指定一个样本的时间执行。不能用于函数调用子系统。
函数包装选项
汽车
——决定子系统出现在生成的代码中。这个值是默认的。内联
——地方子系统代码内联与其他模型的代码。函数
——生成子系统作为函数的代码。可重用的功能
——生成一个可重用(凹)子系统的功能。函数传递所有通过形式参数的输入和输出数据。不直接访问全局变量的函数。
函数名的选择
选择
函数
或可重用的功能
为函数包装使函数名的选择。汽车
——决定了功能。使用子系统名称
——基地功能子系统的名称。用户指定的
——适用于指定的文件名。
文件名称选项
选择
函数
或可重用的功能
为函数包装支持文件名称选项。汽车
——把函数定义模块为父生成系统,或者,如果模型根是母公司model.c
。使用子系统名称
——生成一个单独的文件中。文件的名称是子系统的名称或图书馆。使用函数名
——生成一个单独的文件中。文件的名称是您指定的名称函数名的选择。用户指定的
——适用于指定的,独特的文件名。
函数与单独的数据
当您设置启用函数包装来
函数
。选中时,代码生成器将子系统的内部数据(例如,信号)母公司的数据模型。拥有独立的子系统的数据。
生成可重入代码
嵌入式编码器®支持金宝app可重入代码。可重入代码是一个可重用的编程程序,多个程序可以同时使用。可重入代码是用于操作系统和其他系统软件,使用多线程处理并发事件。可重入代码不维护状态数据,所以没有持久变量的函数。调用程序维护状态变量和状态数据必须通过到函数。多个用户或进程可以共享一个可重入函数的一个副本。
生成可重入代码,您必须首先指定子系统作为可重用通过配置子系统参数函数包装。
在某些情况下,阻止了可重用代码的配置模型。下表列出了一些常见的问题。
原因解决方案
子系统输出提要全球信号添加一个信号转换块数据子系统和全球之间的信号。
生成函数接收数据选择配置参数>(形式参数)通过指针模型引用>通过根输入固定大小的标量值代码生成。
子系统使用全球信号数据使用一个端口通过全局数据在内部子系统的算法。
用面具来传递参数值到图书馆子系统
定义算法参数数据(如获得或系数)之外的一个可重用的库块或子系统的范围,您可以应用面具块或子系统和参数创建一个蒙版。您可以指定一个不同的参数值为每个实例的块或子系统。每个面具参数出现在生成的代码作为一个可重入函数的形式参数。
在这个版本的模型中,子系统PI_ctrl_1
和PI_ctrl_2
是被掩盖的。在每一个面具,的值P
和我
收益是由数据对象等I_Gain_2
和P_Gain_2
。
为原子子系统生成的代码
在准备一个控制算法模型C代码生成和配置数据接口在生成的代码中,你生成代码的根级别的模型。或者,您可以构建一个具体的子系统。
启动子系统的构建,使用上下文菜单。你可以选择这些选项:
构建这个子系统:将子系统作为一个单独的模式,创建了完整的C源文件和头文件。这个选项不支持函数调用子系统。金宝app
生成功能:为子系统生成C代码和创建一个函数包装器。然后您可以模拟原始模型中的代码。这个选项不支持函数调用子系统。金宝app
导出功能:没有调度代码生成C代码的构建这个子系统选择。使用这个选项来构建使用触发器的子系统,如函数调用子系统。
另外,打开嵌入式编码器应用程序,选择子系统和C代码选项卡上,单击构建。
检查生成的代码
这个例子比较了文件生成的完整的系统构建与生成的文件导出功能。您还研究如何屏蔽数据的代码中出现。
三个选项运行构建脚本。然后,检查生成的文件通过单击超链接。
rtwdemo_PCG_Eval_P3.c
完整的构建:是的,阶跃函数
PI_ctrl_1:不
Pos_Command_Arbitration:不
PI_ctrl_1.c
完整的构建:不
PI_ctrl_1:是的触发函数
Pos_Command_Arbitration:不
Pos_Command_Arbitration.c
完整的构建:不
PI_ctrl_1:不
Pos_Command_Arbitration:是的、初始化和功能
PI_Ctrl_Reusable.c
ert_main.c
eval_data.c
(1)eval_data.c
有不同的内容和导出功能构建。完整的构建包括所有的参数模型使用。导出函数只包含子系统所使用的变量。
戴面具的数据在生成的代码
在文件中rtwdemo_PCG_Eval_P3.c
可重入函数的调用网站使用的数据对象P_Gain
,I_Gain
,P_Gain_2
,I_Gain_2
作为参数。
执行顺序对仿真结果的影响
默认情况下,模型®执行子金宝app系统在这个顺序:
PI_ctrl_1
PI_ctrl_2
Pos_Command_Arbitration
对于这个示例,您可以指定两个替代的订单执行。然后,您可以使用测试工具观察的影响仿真结果的执行顺序。子系统Execution_Order_Control
有两个配置,控制执行顺序。选择一个配置,使用子系统的上下文菜单。
改变执行顺序和观察结果。
仿真结果(节气门位置随着时间的推移)根据执行的顺序略有不同。你可以看到当节流阀的请求的时候,最明显的变化的差异。
在本系列的下一个示例,请参阅从模型和生成的代码调用外部C代码。
Nonvirtual子系统模块化函数代码的限制
Nonvirtual子系统块参数函数与单独的数据有以下限制:
可用的参数模型配置一个ERT-based系统目标文件。
nonvirtual子系统的参数是应用不能有多个样本*或连续样本*;即子系统必须单频离散采样时间。
nonvirtual子系统不能包含连续状态。
nonvirtual子系统不能输出函数调用信号。
nonvirtual子系统不能包含noninlined S-functions。
model-wide nonvirtual子系统生成的文件将引用头文件,等
和模型
。h
。模型
_private.h的参数是不相容的经典的调用接口参数。选择这两个参数生成一个错误。
的参数是不相容的
可重用的功能
设置模型配置参数代码接口包装。选择这两个参数生成一个错误。
当您选择一个子系统的参数,模型包含子系统不能包含数据存储内存块与分享跨模型实例选中。看到数据存储内存。