Main Content

Function Reuse in Generated Code

This example shows how to configure an atomic subsystem for generating reusable code. To specify that the code generated for a subsystem execute as an atomic unit, on the Block Parameters dialog box, select the Treat as atomic unit parameter . That parameter enables the Function Packaging parameter on the Code Generation tab. The Function Packaging parameter has these four settings:

  • Inline: Inline the subsystem code

  • Nonreusable function: Function with I/O passed as global data

  • Reusable function: Function with I/O passed as function arguments

  • Auto: Let Simulink Coder optimize based on context

The Reusable function and Auto settings permit the code generator to reuse subsystem code. The Reusable function and Nonreusable function settings enable the Function name options, Function name, and File name options parameters.

If you have an Embedded Coder license, you can configure a nonreusable subsystem to accept arguments.

Example Model

The rtwdemo_ssreuse model contains two identical subsystems, SS1 and SS2. For these subsystems, the Function packaging parameter is set to Reusable function, and the Function name parameter is myfun. The subsystems are parameterized masked subsystems. To see the contents of the masked subsystems, right-click the subsystem blocks and select Mask > Look Under Mask.

model = 'rtwdemo_ssreuse';
open_system(model);

Generate and Inspect Code

Create a temporary folder for the build and inspection process. Open the Simulink Coder or Embedded Coder app. Then, generate and inspect the code.

currentDir=pwd;
[~,cgDir]=rtwdemodir();
rtwbuild(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 15.891s
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_B.SS1,
        rtwdemo_ssreuse_P.T1Data, rtwdemo_ssreuse_P.T1Break);

  /* 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_B.SS2,
        rtwdemo_ssreuse_P.T2Data, rtwdemo_ssreuse_P.T2Break);

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

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

In the model step function, there are two calls to the reusable function, myfun. The mask parameters, T1Break, T1Data, T2Break, and T2Data, are function arguments.

Change the Function Packaging parameter to Inline.

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

Generate and inspect the code.

rtwbuild(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 11.06s
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' */
}

In the model step function, the subsystem code is inlined.

Change the Function Packaging parameter to Nonreusable function. For SS2 , change the Function name parameter to myfun2.

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

Generate and inspect the code.

rtwbuild(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 11.085s
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' */
}

The model step function contains calls to the functions myfun and myfun2. These functions have a void-void interface.

Change the Function Packaging parameter to Auto.

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

For the auto setting, Simulink Coder chooses the optimal format. For this model, the optimal format is a reusable function.

Close the model and clean up.

bdclose(model)
rtwdemoclean;
cd(currentDir)