Main Content

生成代码中的函数重用

此示例说明如何配置原子子系统来生成可重用的代码。要指定为子系统生成的代码作为原子单元执行,请在“模块参数”对话框中选择视为原子单元参数。该参数会启用代码生成选项卡上的函数打包参数。函数打包参数有以下四种设置:

  • Inline:内嵌子系统代码

  • Nonreusable function:I/O 作为全局数据传递的函数

  • Reusable function:I/O 作为函数参数传递的函数

  • Auto:让 Simulink Coder 基于上下文进行优化

Reusable functionAuto 设置允许代码生成器重用子系统代码。Reusable functionNonreusable function 设置支持函数名称选项函数名称以及文件名选项参数。

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

示例模型

rtwdemo_ssreuse 模型包含两个相同的子系统,即 SS1SS2。对于这些子系统,函数打包参数设置为 Reusable function函数名称参数为 myfun。子系统是参数化的封装子系统。要查看封装子系统的内容,请右键点击子系统模块并选择封装 > 查看封装内部

model = 'rtwdemo_ssreuse';
open_system(model);

生成和检查代码

为编译和检查过程创建一个临时文件夹。打开 Simulink CoderEmbedded Coder。然后,生成并检查代码。

currentDir=pwd;
[~,cgDir]=rtwdemodir();
slbuild(model)
### Starting build procedure for: rtwdemo_ssreuse
### Successful completion of build procedure for: rtwdemo_ssreuse

Build Summary

Top model targets built:

Model            Action                        Rebuild Reason                                    
=================================================================================================
rtwdemo_ssreuse  Code generated and compiled.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 11.517s
cfile=fullfile(cgDir, 'rtwdemo_ssreuse_grt_rtw', 'rtwdemo_ssreuse.c');
rtwdemodbtype(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_ssreuse_step(void)
{
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */

  /* Inport: '<Root>/In1' incorporates:
   *  Inport: '<Root>/In2'
   */
  myfun(rtwdemo_ssreuse_U.In1, rtwdemo_ssreuse_U.In2, rtwdemo_ssreuse_P.T1Data,
        rtwdemo_ssreuse_P.T1Break, &rtwdemo_ssreuse_B.SS1);

  /* End of Outputs for SubSystem: '<Root>/SS1' */

  /* Outport: '<Root>/Out1' */
  rtwdemo_ssreuse_Y.Out1 = rtwdemo_ssreuse_B.SS1.LookupTable;

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */

  /* Inport: '<Root>/In1' incorporates:
   *  Inport: '<Root>/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: '<Root>/SS2' */

  /* Outport: '<Root>/Out2' */
  rtwdemo_ssreuse_Y.Out2 = rtwdemo_ssreuse_B.SS2.LookupTable;
}

在模型单步函数中,有两个对可重用函数 myfun 的调用。封装参数 T1BreakT1DataT2BreakT2Data 是函数参数。

函数打包参数更改为 Inline

set_param('rtwdemo_ssreuse/SS1','RTWSystemCode','Inline')
set_param('rtwdemo_ssreuse/SS2','RTWSystemCode','Inline')

生成并检查代码。

slbuild(model)
### Starting build procedure for: rtwdemo_ssreuse
### Successful completion of build procedure for: rtwdemo_ssreuse

Build Summary

Top model targets built:

Model            Action                        Rebuild Reason                   
================================================================================
rtwdemo_ssreuse  Code generated and compiled.  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 10.564s
cfile=fullfile(cgDir, 'rtwdemo_ssreuse_grt_rtw', 'rtwdemo_ssreuse.c');
rtwdemodbtype(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_ssreuse_step(void)
{
  real_T Out1_tmp;

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */
  /* Sum: '<S1>/Sum' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   *  Sum: '<S2>/Sum'
   */
  Out1_tmp = rtwdemo_ssreuse_U.In1 + rtwdemo_ssreuse_U.In2;

  /* End of Outputs for SubSystem: '<Root>/SS2' */

  /* Outport: '<Root>/Out1' incorporates:
   *  Lookup_n-D: '<S1>/Lookup Table'
   *  Sum: '<S1>/Sum'
   */
  rtwdemo_ssreuse_Y.Out1 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P.T1Break,
    rtwdemo_ssreuse_P.T1Data, 10U);

  /* End of Outputs for SubSystem: '<Root>/SS1' */

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */
  /* Outport: '<Root>/Out2' incorporates:
   *  Lookup_n-D: '<S2>/Lookup Table'
   */
  rtwdemo_ssreuse_Y.Out2 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P.T2Break,
    rtwdemo_ssreuse_P.T2Data, 10U);

  /* End of Outputs for SubSystem: '<Root>/SS2' */
}

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

函数打包参数更改为 Nonreusable function。对于 SS2,将函数名称参数更改为 myfun2

set_param('rtwdemo_ssreuse/SS1','RTWSystemCode','Nonreusable function')
set_param('rtwdemo_ssreuse/SS2','RTWSystemCode','Nonreusable function')
set_param('rtwdemo_ssreuse/SS2','RTWFcnName','myfun2')

生成并检查代码。

slbuild(model)
### Starting build procedure for: rtwdemo_ssreuse
### Successful completion of build procedure for: rtwdemo_ssreuse

Build Summary

Top model targets built:

Model            Action                        Rebuild Reason                   
================================================================================
rtwdemo_ssreuse  Code generated and compiled.  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 8.8762s
cfile=fullfile(cgDir, 'rtwdemo_ssreuse_grt_rtw', 'rtwdemo_ssreuse.c');
rtwdemodbtype(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_ssreuse_step(void)
{
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */
  myfun();

  /* End of Outputs for SubSystem: '<Root>/SS1' */

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */
  myfun2();

  /* End of Outputs for SubSystem: '<Root>/SS2' */
}

模型单步函数包含对函数 myfunmyfun2 的调用。这些函数具有 void-void 接口。

函数打包参数更改为 Auto

set_param('rtwdemo_ssreuse/SS1','RTWSystemCode','Auto')
set_param('rtwdemo_ssreuse/SS2','RTWSystemCode','Auto')

对于 auto 设置,Simulink Coder 会选择最佳格式。对于此模型,最佳格式是可重用函数。

关闭模型并进行清理。

bdclose(model)
rtwdemoclean;
cd(currentDir)