Main Content

Generate Subsystem Code as Separate Function and Files

You can configure an atomic subsystem to generate code to a separate function and file. This results in code that is more modular and enables you to unit test code for individual subsystems.

The Function packaging Subsystem block parameter has two settings that cause a subsystem to generate code as a separate function. The Reusable function option generates a function that passes I/O, states, and parameters as function arguments. The Nonreusable function option generates a function that passes I/O, states, and parameters as a combination of function arguments and global data structures.

Subsystem Function Dependence

When generating code for a subsystem, the code can reference global data structures of the model, even if the subsystem function code is in a separate file. Each subsystem code file contains include directives and comments describing the dependencies. The code generator checks for cyclic file dependencies and produces warnings about them at build time. For descriptions of how the code generator packages code, see Manage Build Process File Dependencies.

To generate subsystem function code that is independent of the code generated for the parent model, place the subsystem in a library and configure it as a reusable subsystem, as described in Generate Reusable Code from Library Subsystems Shared Across Models.

If you have Embedded Coder®, you can generate code for library consisting of reusable subsystems that have different function interfaces. For more information, see:

Generate Subsystem as a Reusable Function

1. Open a model that has a subsystem, such as SubsystemAtomic.

SubsystemAtomic

rtwdemo_atomic.png

If you are using Embedded Coder, from the C Code tab, click View Code to open the Code View editor.

2. Right-click the Subsystem block. From the context menu, select Block Parameters (Subsystem).

3. In the Subsystem Parameters dialog box, verify that Treat as atomic unit is selected. With that parameter selected, on the Code Generation tab, the Function packaging parameter is available.

4. Click the Code Generation tab and select Reusable function from the Function packaging parameter. This enables two parameters:

5. Set the File name options parameter to Use subsystem name.

6. Click Apply and close the dialog box.

7. If you are using Embedded Coder, open the Configuration Parameters dialog box. Verify that the model configuration parameter File packaging format is set to Modular.

8. Generate the code.

#include "SS1.h"

/* Include model header file for global data */
#include "SubsystemAtomic.h"
#include "SubsystemAtomic_private.h"

/* Outputs for atomic system: '<Root>/SS1' */
real_T myfun(DW_myfun_T *localDW)
{
  /* DiscreteIntegrator: '<S1>/Integrator' */
  return localDW->Integrator_DSTATE;
}

/* Update for atomic system: '<Root>/SS1' */
void myfun_Update(real_T rtu_In1, DW_myfun_T *localDW)
{
  /* Update for DiscreteIntegrator: '<S1>/Integrator' */
  localDW->Integrator_DSTATE += rtu_In1;
}

The reusable function myfun passes in inputs and states as arguments to the subsystem function.

For more information, see Generate Reentrant Code from Subsystems and Generate Reusable Code from Library Subsystems Shared Across Models.

Generate Subsystem as a Nonreusable Function

1. Open a model that has a subsystem, such as SubsystemAtomic.

SubsystemAtomic

rtwdemo_atomic.png

If you are using Embedded Coder, from the C Code tab, click View Code to open the Code View editor.

2. Right-click the Subsystem block. From the context menu, select Block Parameters (Subsystem).

3. In the Subsystem Parameters dialog box, verify that Treat as atomic unit is selected. With that parameter selected, on the Code Generation tab, the Function packaging parameter is available.

4. Click the Code Generation tab and select Nonreusable function from the Function packaging parameter. This enables two parameters:

5. Set the File name options parameter to Use subsystem name.

6. Click Apply and close the dialog box.

7. If you are using Embedded Coder, open the Configuration Parameters dialog box. Verify that the model configuration parameter File packaging format is set to Modular.

8. Generate the code.

#include "SS1.h"

/* Include model header file for global data */
#include "SubsystemAtomic.h"
#include "SubsystemAtomic_private.h"

/* Outputs for atomic system: '<Root>/SS1' */
void myfun(void)
{
  /* Outport: '<Root>/Out1' incorporates:
   *  DiscreteIntegrator: '<S1>/Integrator'
   */
  SubsystemAtomic_Y.Out1 = SubsystemAtomic_DW.Integrator_DSTATE;
}

/* Update for atomic system: '<Root>/SS1' */
void myfun_Update(void)
{
  /* Update for DiscreteIntegrator: '<S1>/Integrator' */
  SubsystemAtomic_DW.Integrator_DSTATE += SubsystemAtomic_B.Sum;
}

The nonreusable function myfun passes in inputs and states through the global data structures SubsystemAtomic_Y and SubsystemAtomic_DW.

Related Topics