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
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:
The Function name options parameter controls the naming of the generated function.
The File name options parameter controls the naming of the generated file.
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 (Embedded Coder) 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
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:
The Function name options parameter controls the naming of the generated function.
The File name options parameter controls the naming of the generated file.
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 (Embedded Coder) 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
.