主要内容

从子系统生成可重入代码

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

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

配置子系统块参数。

  1. 当子系统为虚拟子系统时,选择block参数当作原子单位对待开启功能包装参数。

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

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

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

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

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

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

    如果您正在使用嵌入式编码器®,您可以使用标识符格式控件。看到标识符的格式控制

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

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

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

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

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

    其他注意事项:

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

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

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

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

如果子系统A有掩码参数bK子系统B有掩码参数cK,代码重用是不可能的。代码生成器为子系统A和B生成独立的函数。如果您为子系统A和B设置不同的块参数,则不可能实现代码重用。

生成代码中的函数重用

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

  • 内联:内联子系统代码

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

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

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

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

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

示例模型

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

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

生成和检查代码

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

currentDir = pwd;[~, cgDir] = rtwdemodir ();slbuild(模型)
###成功完成rtwdemo_ssreuse的构建过程:模型重建行动的原因  ================================================================================================ rtwdemo_ssreuse代码生成和编译代码生成信息文件不存在。建造时间:0小时0米17.362秒
用= fullfile (cgDir,“rtwdemo_ssreuse_grt_rtw”“rtwdemo_ssreuse.c”);rtwdemodbtype(用“/ *模型步骤”/ *初始化模型的1 0);
/* Model step function */ void rtwdemo_ssreuse_step(void) {/* Outputs for Atomic SubSystem: '/SS1' */ /* import: '/In1' includes: * import: '/In2' */ myfun(rtwdemo_ssreuse_U. aspx);三机一体,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代码生成和编译生成的代码是过时了。建造时间:0小时0米12.521秒
用= fullfile (cgDir,“rtwdemo_ssreuse_grt_rtw”“rtwdemo_ssreuse.c”);rtwdemodbtype(用“/ *模型步骤”/ *初始化模型的1 0);
/*模型步长函数*/ void rtwdemo_ssreuse_step(void) {real_T Out1_tmp;/* Outputs for Atomic SubSystem: '/SS2' */ /* Outputs for Atomic SubSystem: '/SS1' */ /* Sum: '/Sum' includes: * import: '/In1' * import: '/In2' * Sum: '/Sum' */ Out1_tmp = rtwdemo_ssreuse_U. txt . txt . txt . txt . txt . txt。三机一体+ rtwdemo_ssreuse_U.In2;/* output for子系统:'/SS2' */ /* Outport: '/Out1'合并:* Lookup_n-D: '/Lookup Table' * Sum: '/Sum' */ rtwdemo_ssreuse_Y. txt 'Out1 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P。T1Break rtwdemo_ssreuse_P。T1Data 10 u);/* output for SubSystem: '/SS1' */ /* Outputs for Atomic SubSystem: '/SS2' */ /* Outport: '/Out2' includes: * Lookup_n-D: '/Lookup Table' */ rtwdemo_ssreuse_Y. txt . txt . txt . txt . txt . txt . txt . txt . txt . txt . txt . txt . txt . txt . txt . txt。Out2 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P。T2Break rtwdemo_ssreuse_P。T2Data 10 u);/*子系统输出结束:'/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代码生成和编译生成的代码是过时了。建造时间:0小时0米13.182秒
用= fullfile (cgDir,“rtwdemo_ssreuse_grt_rtw”“rtwdemo_ssreuse.c”);rtwdemodbtype(用“/ *模型步骤”/ *初始化模型的1 0);
/* Model step函数*/ void rtwdemo_ssreuse_step(void){/*输出原子子系统:'/SS1' */ myfun();/* output for子系统:'/SS1' */ /* output for Atomic子系统:'/SS2' */ myfun2();/*子系统输出结束:'/SS2' */}

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

改变函数包装参数汽车

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

汽车设置,Simuli金宝appnk Coder选择最佳格式。对于这个模型,最佳格式是可重用的功能。

关闭模型并清理。

bdclose rtwdemoclean(模型);cd (currentDir)

限制

  • 代码生成器使用校验和来确定子系统是否相同和可重用。子系统代码在以下情况下不被重用:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • 作用域块(启用数据日志记录)

    • 不能满足某些条件的s -功能块(参见用于代码重用的s -函数

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

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

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

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

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

    • 包含一个或多个Model块。

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

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

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

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

  • 如果模型中有同一子系统的多个实例,并且一个子系统由Constant块提供,而另一个子系统不是,则不能重用该子系统。要绕过这个限制,请在子系统之前插入一个Signal Conversion块。

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

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

    • 如果子系统没有被库链接,代码生成器就会发出错误。

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

相关的话题