Skip to Main Content Skip to Search
Product Documentation

Atomic Subsystem Code

About Nonvirtual Subsystem Code Generation

The Embedded Coder software provides a subsystem option, Function with separate data, that allows you to generate modular function code for nonvirtual subsystems, including atomic subsystems and conditionally executed subsystems.

By default, the generated code for a nonvirtual subsystem does not separate a subsystem's internal data from the data of its parent Simulink model. This can make it difficult to trace and test the code, particularly for nonreusable subsystems. Also, in large models containing nonvirtual subsystems, data structures can become large and potentially difficult to compile.

The Subsystem Parameters dialog box option Function with separate data allows you to generate subsystem function code in which the internal data for a nonvirtual subsystem is separated from its parent model and is owned by the subsystem. As a result, the generated code for the subsystem is easier to trace and test. The data separation also tends to reduce the size of data structures throughout the model.

To be able to use this option,

To configure your subsystem for generating modular function code, you invoke the Subsystem Parameters dialog box and make a series of selections to display and enable the Function with separate data option. See Configuring Nonvirtual Subsystems for Generating Modular Function Code and Examples of Modular Function Code for Nonvirtual Subsystems for details. For limitations that apply, see Nonvirtual Subsystem Modular Function Code Limitations.

For more information about generating code for atomic subsystems, see the sections Subsystems and Generating Code and Executables from Subsystems in the Simulink Coder documentation.

Configuring Nonvirtual Subsystems for Generating Modular Function Code

This section summarizes the steps to configure a subsystem in a Simulink model for modular function code generation.

  1. Verify that the Simulink model containing the subsystem uses an ERT-based system target file (see the System target file parameter on the Code Generation pane of the Configuration Parameters dialog box).

  2. In your Simulink model, select the subsystem for which you want to generate modular function code and launch the Subsystem Parameters dialog box (for example, right-click the subsystem and select Subsystem Parameters). The dialog box for an atomic subsystem is shown below. (In the dialog box for a conditionally executed subsystem, the dialog box option Treat as atomic unit is greyed out, and you can skip Step 3.)

  3. If the Subsystem Parameters dialog box option Treat as atomic unit is available for selection but not selected, the subsystem is neither atomic nor conditionally executed. Select the option Treat as atomic unit, which enables Function packaging on the Code Generation tab. Select the Code Generation tab.

  4. For the Function packaging parameter, select the value Function. After you make this selection, the Function with separate data option is displayed.

      Note   Before you generate nonvirtual subsystem function code with the Function with separate data option selected, you might want to generate function code with the option deselected and save the generated function .c and .h files in a separate directory for later comparison.

  5. Select the Function with separate data option. After you make this selection, additional configuration parameters are displayed.

      Note   To control the naming of the subsystem function and the subsystem files in the generated code, you can modify the subsystem parameters Function name options and File name options.

  6. To save your subsystem parameter settings and exit the dialog box, click OK.

This completes the subsystem configuration for generating modular function code. You can now generate the code for the subsystem and examine the generated files, including the function .c and .h files named according to your subsystem parameter specifications. For more information on generating code for nonvirtual subsystems, see Subsystems in the Simulink Coder documentation. For examples of generated subsystem function code, see Examples of Modular Function Code for Nonvirtual Subsystems.

Examples of Modular Function Code for Nonvirtual Subsystems

To illustrate the effect of selecting the Function with separate data option for a nonvirtual subsystem, the following procedure generates atomic subsystem function code with and without the option selected and compares the results.

  1. Open MATLAB and launch rtwdemo_atomic.mdl using the MATLAB command rtwdemo_atomic. Examine the Simulink model.

  2. Double-click the SS1 subsystem and examine the contents. (You can close the subsystem window when you are finished.)

  3. Use the Configuration Parameters dialog box to change the model's System target file from GRT to ERT. For example, from the Simulink window, select Simulation > Configuration Parameters, select the Code Generation pane, select System target file ert.tlc, and click OK twice to confirm the change.

  4. Create a variant of rtwdemo_atomic.mdl that illustrates function code without data separation.

    1. In the Simulink view of rtwdemo_atomic.mdl, right-click the SS1 subsystem and select Subsystem Parameters. In the Subsystem Parameters dialog box, verify that

      • On the Main tab, Treat as atomic unit is selected

      • On the Code Generation tab, User specified is selected for Function name options

      • On the Code Generation tab, myfun is specified for Function name

    2. In the Subsystem Parameters dialog box, on the Code Generation tab

      1. Select the value Function for the Function packaging parameter. After this selection, additional parameters and options will appear.

      2. Select the value Use function name for the File name options parameter. This selection is optional but simplifies the later task of code comparison by causing the atomic subsystem function code to be generated into the files myfun.c and myfun.h.

      Do not select the option Function with separate data. Click Apply to apply the changes and click OK to exit the dialog box.

    3. Save this model variant to a personal work directory, for example, d:/atomic/rtwdemo_atomic1.mdl.

  5. Create a variant of rtwdemo_atomic.mdl that illustrates function code with data separation.

    1. In the Simulink view of rtwdemo_atomic1.mdl (or rtwdemo_atomic.mdl with step 3 reapplied), right-click the SS1 subsystem and select Subsystem Parameters. In the Subsystem Parameters dialog box, verify that

      • On the Main tab, Treat as atomic unit is selected

      • On the Code Generation tab, Function is selected for Function packaging

      • On the Code Generation tab, User specified is selected for Function name options

      • On the Code Generation tab, myfun is specified for Function name

      • On the Code Generation tab, Use function name is specified for File name options

    2. In the Subsystem Parameters dialog box, on the Code Generation tab, select the option Function with separate data. Click Apply to apply the change and click OK to exit the dialog box.

    3. Save this model variant, using a different name than the first variant, to a personal work directory, for example, d:/atomic/rtwdemo_atomic2.mdl.

  6. Generate code for each model, d:/atomic/rtwdemo_atomic1.mdl and d:/atomic/rtwdemo_atomic2.mdl.

  7. In the generated code directories, compare the model.c/.h and myfun.c/.h files generated for the two models. (In this example, there are no significant differences in the generated variants of ert_main.c, model_private.h, model_types.h, or rtwtypes.h.)

H File Differences for Nonvirtual Subsystem Function Data Separation

The differences between the H files generated for rtwdemo_atomic1.mdl and rtwdemo_atomic2.mdl help illustrate the effect of selecting the Function with separate data option for nonvirtual subsystems.

  1. Selecting Function with separate data causes typedefs for subsystem data to be generated in the myfun.h file for rtwdemo_atomic2:

    /* Block signals for system '<Root>/SS1' */
    typedef struct {
      real_T Integrator;                    /* '<S1>/Integrator' */
    } rtB_myfun;
    
    /* Block states (auto storage) for system '<Root>/SS1' */
    typedef struct {
      real_T Integrator_DSTATE;             /* '<S1>/Integrator' */
    } rtDW_myfun;

    By contrast, for rtwdemo_atomic1, typedefs for subsystem data belong to the model and appear in rtwdemo_atomic1.h:

    /* Block signals (auto storage) */
    typedef struct {
    ...
        real_T Integrator;                  /* '<S1>/Integrator' */
    } BlockIO_rtwdemo_atomic1;
    
    /* Block states (auto storage) for system '<Root>' */
    typedef struct {
      real_T Integrator_DSTATE;             /* '<S1>/Integrator' */
    } D_Work_rtwdemo_atomic1;
  2. Selecting Function with separate data generates the following external declarations in the myfun.h file for rtwdemo_atomic2:

    /* Extern declarations of internal data for 'system '<Root>/SS1'' */
    extern rtB_myfun rtwdemo_atomic2_myfunB;
    
    extern rtDW_myfun rtwdemo_atomic2_myfunDW;
    
    extern void myfun_initialize(void);

    By contrast, the generated code for rtwdemo_atomic1 contains model-level external declarations for the subsystem's BlockIO and D_Work data, in rtwdemo_atomic1.h:

    /* Block signals (auto storage) */
    extern BlockIO_rtwdemo_atomic1 rtwdemo_atomic1_B;
    
    /* Block states (auto storage) */
    extern D_Work_rtwdemo_atomic1 rtwdemo_atomic1_DWork;

C File Differences for Nonvirtual Subsystem Function Data Separation

The differences between the C files generated for rtwdemo_atomic1.mdl and rtwdemo_atomic2.mdl illustrate the key effects of selecting the Function with separate data option for nonvirtual subsystems.

  1. Selecting Function with separate data causes a separate subsystem initialize function, myfun_initialize, to be generated in the myfun.c file for rtwdemo_atomic2:

    void myfun_initialize(void) {
      {
        ((real_T*)&rtwdemo_atomic2_myfunB.Integrator)[0] = 0.0;
      }
      rtwdemo_atomic2_myfunDW.Integrator_DSTATE = 0.0;
    }

    The subsystem initialize function in myfun.c is invoked by the model initialize function in rtwdemo_atomic2.c:

    /* Model initialize function */
    
    void rtwdemo_atomic2_initialize(void)
    {
    ...
    
      /* Initialize subsystem data */
      myfun_initialize();
    }

    By contrast, for rtwdemo_atomic1, subsystem data is initialized by the model initialize function in rtwdemo_atomic1.c:

    /* Model initialize function */
    
    void rtwdemo_atomic1_initialize(void)
    {
    ...
      /* block I/O */
      {
     ...
        ((real_T*)&rtwdemo_atomic1_B.Integrator)[0] = 0.0;
      }
    
      /* states (dwork) */
    
      rtwdemo_atomic1_DWork.Integrator_DSTATE = 0.0;
    ...
    }
  2. Selecting Function with separate data generates the following declarations in the myfun.c file for rtwdemo_atomic2:

    /* Declare variables for internal data of system '<Root>/SS1' */
    rtB_myfun rtwdemo_atomic2_myfunB;
    
    rtDW_myfun rtwdemo_atomic2_myfunDW;

    By contrast, the generated code for rtwdemo_atomic1 contains model-level declarations for the subsystem's BlockIO and D_Work data, in rtwdemo_atomic1.c:

    /* Block signals (auto storage) */
    BlockIO_rtwdemo_atomic1 rtwdemo_atomic1_B;
    
    /* Block states (auto storage) */
    D_Work_rtwdemo_atomic1 rtwdemo_atomic1_DWork;
  3. Selecting Function with separate data generates identifier naming that reflects the subsystem orientation of data items. Notice the references to subsystem data in subsystem functions such as myfun and myfun_update or in the model's model_step function. For example, compare this code from myfun for rtwdemo_atomic2

    /* DiscreteIntegrator: '<S1>/Integrator' */
    rtwdemo_atomic2_myfunB.Integrator = rtwdemo_atomic2_myfunDW.Integrator_DSTATE;

    to the corresponding code from myfun for rtwdemo_atomic1.

    /* DiscreteIntegrator: '<S1>/Integrator' */
    rtwdemo_atomic1_B.Integrator = rtwdemo_atomic1_DWork.Integrator_DSTATE;

Nonvirtual Subsystem Modular Function Code Limitations

The nonvirtual subsystem option Function with separate data has the following limitations:

  


Related Products & Applications

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.

 © 1984-2012- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS