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 GeneratedCodeFunctionReuse 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 = 'GeneratedCodeFunctionReuse';
open_system(model);

Generate and Inspect Code

Open the Simulink Coder or Embedded Coder app. Then, generate and inspect the code.

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

Build Summary

Top model targets:

Model                       Build Reason                                         Status                        Build Duration
=============================================================================================================================
GeneratedCodeFunctionReuse  Information cache folder or artifacts were missing.  Code generated and compiled.  0h 0m 11.484s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 12.248s
cfile=fullfile(pwd, 'GeneratedCodeFunctionReuse_grt_rtw', 'GeneratedCodeFunctionReuse.c');
coder.example.extractLines(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void GeneratedCodeFunctionReuse_step(void)
{
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */

  /* Inport: '<Root>/In1' incorporates:
   *  Inport: '<Root>/In2'
   */
  myfun(GeneratedCodeFunctionReuse_U.In1, GeneratedCodeFunctionReuse_U.In2,
        GeneratedCodeFunctionReuse_P.T1Data,
        GeneratedCodeFunctionReuse_P.T1Break, &GeneratedCodeFunctionReuse_B.SS1);

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

  /* Outport: '<Root>/Out1' */
  GeneratedCodeFunctionReuse_Y.Out1 =
    GeneratedCodeFunctionReuse_B.SS1.LookupTable;

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

  /* Inport: '<Root>/In1' incorporates:
   *  Inport: '<Root>/In2'
   */
  myfun(GeneratedCodeFunctionReuse_U.In1, GeneratedCodeFunctionReuse_U.In2,
        GeneratedCodeFunctionReuse_P.T2Data,
        GeneratedCodeFunctionReuse_P.T2Break, &GeneratedCodeFunctionReuse_B.SS2);

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

  /* Outport: '<Root>/Out2' */
  GeneratedCodeFunctionReuse_Y.Out2 =
    GeneratedCodeFunctionReuse_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('GeneratedCodeFunctionReuse/SS1','RTWSystemCode','Inline')
set_param('GeneratedCodeFunctionReuse/SS2','RTWSystemCode','Inline')

Generate and inspect the code.

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

Build Summary

Top model targets:

Model                       Build Reason                     Status                        Build Duration
=========================================================================================================
GeneratedCodeFunctionReuse  Generated code was out of date.  Code generated and compiled.  0h 0m 9.1124s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 10.035s
cfile=fullfile(pwd, 'GeneratedCodeFunctionReuse_grt_rtw', 'GeneratedCodeFunctionReuse.c');
coder.example.extractLines(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void GeneratedCodeFunctionReuse_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 = GeneratedCodeFunctionReuse_U.In1 + GeneratedCodeFunctionReuse_U.In2;

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

  /* Outport: '<Root>/Out1' incorporates:
   *  Lookup_n-D: '<S1>/Lookup Table'
   *  Sum: '<S1>/Sum'
   */
  GeneratedCodeFunctionReuse_Y.Out1 = look1_binlx(Out1_tmp,
    GeneratedCodeFunctionReuse_P.T1Break, GeneratedCodeFunctionReuse_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'
   */
  GeneratedCodeFunctionReuse_Y.Out2 = look1_binlx(Out1_tmp,
    GeneratedCodeFunctionReuse_P.T2Break, GeneratedCodeFunctionReuse_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('GeneratedCodeFunctionReuse/SS1','RTWSystemCode','Nonreusable function')
set_param('GeneratedCodeFunctionReuse/SS2','RTWSystemCode','Nonreusable function')
set_param('GeneratedCodeFunctionReuse/SS2','RTWFcnName','myfun2')

Generate and inspect the code.

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

Build Summary

Top model targets:

Model                       Build Reason                     Status                        Build Duration
=========================================================================================================
GeneratedCodeFunctionReuse  Generated code was out of date.  Code generated and compiled.  0h 0m 8.5148s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 9.4217s
cfile=fullfile(pwd, 'GeneratedCodeFunctionReuse_grt_rtw', 'GeneratedCodeFunctionReuse.c');
coder.example.extractLines(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void GeneratedCodeFunctionReuse_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('GeneratedCodeFunctionReuse/SS1','RTWSystemCode','Auto')
set_param('GeneratedCodeFunctionReuse/SS2','RTWSystemCode','Auto')

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