主要内容

从子系统生成可重入代码

通过将子系统配置为作为参数传递数据的可重用函数,可以减少代码生成器为相同的原子子系统生成的代码量(例如,rtB_ *对于块输入和输出,rtDW_ *对于连续状态,和rtP_ *参数)。默认情况下,代码生成器生成子系统代码,子系统代码通过共享访问共享内存中的全局数据结构与其他代码通信。通过将数据作为参数传递,代码可以重入。代码的每个实例都维护自己的惟一数据。

为了配置子系统的可重用性和可重入性,请以相同的方式配置相同子系统的掩码和块参数。代码生成器执行校验和以确定子系统是否相同以及代码是否可重用。如果代码是可重用的,代码生成器将生成可重用的、可重入的函数代码的单个实例。

配置子系统块参数。

  1. 如果子系统为虚拟子系统,请选择块参数将其视为原子单位启用函数打包参数。

  2. 设置块参数函数包装可重用的功能.代码生成器为每个子系统生成带有参数的单独函数。选择可重用的功能还启用其他参数,可用于控制代码生成器为子系统代码生成的函数和文件的名称。

  3. 为块参数选择一个值函数名选项.要生成可重用的、可重入的代码,请为相同的子系统指定相同的设置。

    • 若要让代码生成器确定函数名,请选择汽车

    • 若要使用子系统名称,或对于库块,使用库块的名称,请选择使用子系统名称

    • 显示块参数函数名并输入一个唯一的,有效的C/ c++函数名,选择用户指定的

    如果在一个模型引用层次结构中存在同一个子系统的多个实例,请选择汽车

    如果你使用嵌入式编码器®,可以使用标识符格式控件。看到标识符格式控制(嵌入式编码)

  4. 文件名选项.要生成可重用的、可重入的代码,请为相同的子系统指定相同的设置。

    • 让代码生成器决定文件命名选择汽车

    • 若要使用子系统名称,或对于库块,则选择库块的名称使用子系统名称

    • 要使用由块参数指定的函数名函数名选项选择使用函数名

    • 显示块参数文件名称(无扩展名)并输入文件名称,不包括扩展名(例如,.c. cpp)选择用户指定的

    其他注意事项:

    • 如果在一个模型引用层次结构中存在同一个子系统的多个实例,请选择汽车

    • 如果代码生成器没有为子系统生成单独的文件,则函数代码将放在子系统的父系统生成的文件中。如果父类是模型本身,代码生成器将函数代码放在其中模型.c模型. cpp

    • 如果生成的代码处于源代码控制之下,请指定一个值汽车.该规范防止在修改和重新构建模型时更改生成的文件名。

    • 如果您选择使用子系统名称,如果模型包含model块,或者正在为模型生成模型引用目标,代码生成器将修改子系统文件名。在这些情况下,代码生成器使用文件名模型子系统.c

如果子系统A有mask参数b而且K子系统B有掩码参数c而且K,代码重用是不可能的。代码生成器为子系统A和B生成单独的函数。如果为子系统A和B设置不同的块参数,代码重用是不可能的。

生成代码中的函数重用

这个例子展示了如何配置原子子系统来生成可重用代码。要指定为子系统生成的代码作为原子单元执行,请在“块参数”对话框上选择将其视为原子单位参数。该参数启用函数包装参数。代码生成选项卡。的函数包装参数有四个设置:

  • 内联:内联子系统代码

  • 那种一次性的功能:将I/O作为全局数据传递的函数

  • 可重用的功能:将I/O作为函数参数传递的函数

  • 汽车:让Simu金宝applink Coder基于上下文进行优化

可重用的功能而且汽车设置允许代码生成器重用子系统代码。的可重用的功能而且那种一次性的功能设置启用函数名选项函数名,文件名称选项参数。

如果您有嵌入式Coder®许可证,您可以配置一个不可重用的子系统来接受参数。

示例模型

rtwdemo_ssreuse模型包含两个相同的子系统,魔法石,第1章而且SS2.对于这些子系统,函数包装参数设置为可重用的函数,以及函数名参数是myfun.这些子系统是参数化的屏蔽子系统。要查看屏蔽子系统的内容,右键单击子系统块并选择面具>看下面具

模型=“rtwdemo_ssreuse”;open_system(模型);

生成和检查代码

为构建和检查过程创建临时文件夹。打开金宝app仿真软件编码器嵌入式编码器然后,生成并检查代码。

currentDir = pwd;[~, cgDir] = rtwdemodir ();slbuild(模型)
# # #开始构建过程:rtwdemo_ssreuse # # #成功完成构建过程:rtwdemo_ssreuse模型建立目标:总结构建模型重建行动的理由  ================================================================================================= rtwdemo_ssreuse代码生成和编译。代码生成信息文件不存在。构建1 / 1模型(0个模型已经更新)构建持续时间:0h 0m 10.873秒
用= fullfile (cgDir,“rtwdemo_ssreuse_grt_rtw”“rtwdemo_ssreuse.c”);rtwdemodbtype(用'/*模拟步骤'/*模型初始化, 1, 0);
/*模型步函数*/ void rtwdemo_ssreuse_step(void){/*原子子系统的输出:'<根>/SS1' */ /*输入:'<根>/In1'合并:*输入:'<根>/In2' */ myfun(rtwdemo_ssreuse_U. 0)。三机一体,rtwdemo_ssreuse_U。In2 rtwdemo_ssreuse_P。T1Data,rtwdemo_ssreuse_P.T1Break, &rtwdemo_ssreuse_B.SS1); /* End of Outputs for SubSystem: '/SS1' */ /* Outport: '/Out1' */ rtwdemo_ssreuse_Y.Out1 = rtwdemo_ssreuse_B.SS1.LookupTable; /* Outputs for Atomic SubSystem: '/SS2' */ /* Inport: '/In1' incorporates: * Inport: '/In2' */ myfun(rtwdemo_ssreuse_U.In1, rtwdemo_ssreuse_U.In2, rtwdemo_ssreuse_P.T2Data, rtwdemo_ssreuse_P.T2Break, &rtwdemo_ssreuse_B.SS2); /* End of Outputs for SubSystem: '/SS2' */ /* Outport: '/Out2' */ rtwdemo_ssreuse_Y.Out2 = rtwdemo_ssreuse_B.SS2.LookupTable; }

在模型阶跃函数中,有两次对可重用函数的调用,myfun.掩码参数,T1BreakT1DataT2Break,T2Data,为函数实参。

改变函数包装参数内联

set_param (“rtwdemo_ssreuse(魔法石,第1章”“RTWSystemCode”“内联”) set_param (“SS2 rtwdemo_ssreuse /”“RTWSystemCode”“内联”

生成并检查代码。

slbuild(模型)
# # #开始构建过程:rtwdemo_ssreuse # # #成功完成构建过程:rtwdemo_ssreuse模型建立目标:总结构建模型重建行动的理由  ================================================================================ rtwdemo_ssreuse代码生成和编译。生成的代码已经过时。构建1 / 1模型(0个模型已经更新)构建持续时间:0h 0m 7.7591s
用= fullfile (cgDir,“rtwdemo_ssreuse_grt_rtw”“rtwdemo_ssreuse.c”);rtwdemodbtype(用'/*模拟步骤'/*模型初始化, 1, 0);
/*模型步长函数*/ void rtwdemo_ssreuse_step(void) {real_T Out1_tmp;/* output for Atomic SubSystem: '<根>/SS2' */ /* output for Atomic SubSystem: '<根>/SS1' */ /* Sum: '/Sum'合并:* Inport: '<根>/In1' * Inport: '<根>/In2' * Sum: '/Sum' */ Out1_tmp = rtwdemo_ssreuse_U。In1 + rtwdemo_ssreuse_U.In2;/* End of Outputs for SubSystem: '/SS2' */ /* Outport: '/Out1'合并:* Lookup_n-D: '/Lookup Table' * Sum: '/Sum' */ rtwdemo_ssreuse_Y. Outport: '/Out1'Out1 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P。T1Break rtwdemo_ssreuse_P。T1Data 10 u);/* End of Outputs for SubSystem: '/SS1' */ /* Outputs for Atomic SubSystem: '/SS2' */ /* Outport: '/Out2'合并:* Lookup_n-D: '/Lookup Table' */ rtwdemo_ssreuse_Y。Out2 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P。T2Break rtwdemo_ssreuse_P。T2Data 10 u);/* output for SubSystem: '/SS2' */}

在模型步骤函数中,子系统代码是内联的。

改变函数包装参数那种一次性的功能.为SS2,更改函数名参数myfun2

set_param (“rtwdemo_ssreuse(魔法石,第1章”“RTWSystemCode”“那种一次性函数”) set_param (“SS2 rtwdemo_ssreuse /”“RTWSystemCode”“那种一次性函数”) set_param (“SS2 rtwdemo_ssreuse /”“RTWFcnName”“myfun2”

生成并检查代码。

slbuild(模型)
# # #开始构建过程:rtwdemo_ssreuse # # #成功完成构建过程:rtwdemo_ssreuse模型建立目标:总结构建模型重建行动的理由  ================================================================================ rtwdemo_ssreuse代码生成和编译。生成的代码已经过时。构建1 / 1模型(0个模型已经更新)构建持续时间:0h 0m 7.9978s
用= fullfile (cgDir,“rtwdemo_ssreuse_grt_rtw”“rtwdemo_ssreuse.c”);rtwdemodbtype(用'/*模拟步骤'/*模型初始化, 1, 0);
/*模型步函数*/ void rtwdemo_ssreuse_step(void){/*输出原子子系统:'<根>/SS1' */ myfun();/* output for SubSystem: '/SS1' */ /* output for Atomic SubSystem: '/SS2' */ myfun2();/* output for SubSystem: '/SS2' */}

模型步骤函数包含对函数的调用myfun而且myfun2.这些函数有一个void-void接口。

改变函数包装参数汽车

set_param (“rtwdemo_ssreuse(魔法石,第1章”“RTWSystemCode”“汽车”) set_param (“SS2 rtwdemo_ssreuse /”“RTWSystemCode”“汽车”

汽车设置后,Simul金宝appink Coder会选择最佳格式。对于这个模型,最佳格式是可重用函数。

关闭模型并清理。

bdclose rtwdemoclean(模型);cd (currentDir)

限制

子系统的代码重用是一个优化特性,不能保证。下面列出的子系统中代码重用的限制并不详尽。

  • 代码生成器使用校验和来确定子系统是否相同且可重用。子系统代码不能被重用,如果:

    • 在块和数据对象中,使用符号指定尺寸。

    • 端口在各个子系统之间有不同的采样时间、数据类型、复杂性、帧状态或维度。

    • 子系统的输出被标记为全局信号。

    • 子系统包含具有不同名称或参数设置的相同块。

    • 子系统的输出连接到合并块的输出合并block配置了一个自定义存储类,该类在C代码中实现为不可寻址内存(例如,设置).

    • 子系统的输入是非标量的,并配置了一个自定义存储类,该类在C代码中实现为不可寻址内存。

    • 一个被屏蔽的子系统有一个非标量的参数,并且配置了一个自定义存储类,这个类在C代码中实现为不可寻址内存。

    • 函数调用子系统在设置模型配置参数时使用掩码参数默认参数行为可调.要重用掩码函数调用子系统,请将其放置在没有掩码的新原子子系统中。然后将Trigger块从屏蔽子系统移动到原子子系统。

    • 子系统中的块使用部分可调表达式.一些部分可调表达式禁止代码重用。

      部分可调表达式是包含一个或多个可调变量和一个不可调表达式的表达式。例如,假设您创建了可调变量K与价值15.23还有可调变量P与价值(5、7、9).表达式K + P '部分可调表达式是因为表达式P '不可调。有关可调表达式限制的详细信息,请参见可调表达式限制

  • 对于包含可重用的s功能块的子系统,这些块必须满足中列出的要求代码重用的s函数

  • 如果您选择可重用的功能,并且代码生成器确定您不能为子系统重用代码,它将生成一个不可重用的单独函数。代码生成报告可能显示单独的函数是可重用的,即使只有一个子系统使用它。如果您希望在这种情况下代码生成器内联子系统代码(而不是作为函数部署),请设置函数包装汽车

  • 如果可重用子系统使用共享的本地数据存储,并且为模型数据元素配置默认映射,则将默认存储类映射保留为类别共享本地数据存储设置为默认的

  • 在子系统中使用这些块可以防止子系统代码被重用:

    • 范围块(启用了数据日志记录)

    • 未能满足某些标准的s -函数块(参见代码重用的s函数

    • 到文件块(启用数据日志记录)

    • 到工作区块(启用了数据日志记录)

  • 对于可重用的库子系统(跨引用模型共享的子系统),代码生成器使用校验和来确定子系统是否相同。代码生成器将可重用的库子系统代码放在共享实用程序文件夹中,并且可重用的代码独立于顶层模型或参考模型的生成代码。例如,可重用库子系统代码不包括模型.h模型_types.h

    代码生成器放在共享实用程序文件夹中并依赖于模型代码的可重用代码不能编译。如果代码生成器确定可重用的库子系统代码依赖于模型代码,那么可重用的子系统代码就不会放在共享实用程序文件夹中。代码生成器生成依赖于模型代码的代码,当可重用库子系统:

    • 包含使用与时间相关的功能的块,例如步骤块、连续时间块或多速率块。

    • 包含一个或多个Model块。

    • 包含非内联的子系统或可重用的库子系统。

    • 包含带有存储类的信号或参数,该存储类将数据声明放在下的文件中模型_ert_rtw(例如,ExportedGlobal存储类将数据放在模型.c

    • 包含用户定义的存储类,如Enumeration、Simulink。金宝app信号,仿真软件。金宝appParameter, and so on where数据范围未设置为出口.代码生成器可以将类型定义放在模型_types.h

    • 是生成预处理器条件的变体子系统。代码生成器放置定义变量对象的预处理器指令模型_types.h

  • 如果模型中有同一个子系统的多个实例,并且一个子系统由Constant块提供,而另一个子系统不是,那么您就不能重用一个子系统。为了解决这个限制,在子系统之前插入一个信号转换块。

  • 两个具有不同校验和的可重用子系统不能在生成的代码中共享相同的函数。中为两个子系统指定相同的函数名时块参数(子系统)>代码生成>函数名

    • 如果子系统是库链接的,代码生成器将修改函数名以生成惟一的函数名。代码生成器使用子系统命名规则来生成函数名。

    • 如果子系统不是库链接的,代码生成器就会发出一个错误。

上述限制也适用于基于库的代码生成。有关更多信息,请参见基于库的可重用库子系统代码生成(嵌入式编码)

相关的话题