Documentation

Generate Modular Function Code

The Embedded Coder®software provides a Subsystem Parameters dialog box option,傅nction 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.

About Nonvirtual Subsystem Code Generation

傅nction with separate dataallows 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. The subsystem data structure is declared independently from the parent model data structures. A subsystem with separate data has its own block I/O andDWorkdata structure. As a result, the generated code for the subsystem is easier to trace and test. The data separation also tends to reduce the maximum size of global data structures throughout the model, because they are split into multiple data structures.

To use the傅nction with separate dataparameter,

  • Your model must use an ERT-based system target file (requires a Embedded Coder license).

  • Your subsystem must be configured to be atomic or conditionally executed. For more information, seeSystems and Subsystems(Simulink).

  • Your subsystem must use theNonreusable functionsetting forCode Generation>傅nction packaging.

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傅nction with separate dataoption. SeeConfigure Subsystem for Generating Modular Function CodeandModular Function Code for Nonvirtual Subsystemsfor details. For limitations that apply, seeNonvirtual Subsystem Modular Function Code Limitations.

For more information about generating code for atomic subsystems, see the sectionsControl Generation of Subsystem Functions(Simulink Coder) andGenerate Code and Executables for Individual Subsystems(Simulink Coder).

Configure Subsystem for Generating Modular Function Code

This section summarizes the steps to configure a nonvirtual 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 theSystem target fileparameter on theCode Generationpane of the Configuration Parameters dialog box).

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

  3. If the Subsystem Parameters dialog box optionTreat as atomic unitis available for selection but not selected, the subsystem is neither atomic nor conditionally executed. Select the optionTreat as atomic unit, which enables傅nction packagingon theCode Generationtab. Select theCode Generationtab.

  4. For the傅nction packagingparameter, select the valueNonreusable function. After you make this selection, the傅nction with separate dataoption is displayed.

    Note

    Before you generate nonvirtual subsystem function code with the傅nction with separate dataoption selected, you might want to generate function code with the optiondeselectedand save the generated function.cand.hfiles in a separate directory for later comparison.

  5. Select the傅nction with separate dataoption. 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傅nction name optionsandFile name options.

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

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.cand.hfiles named according to your subsystem parameter specifications. For more information on generating code for nonvirtual subsystems, seeControl Generation of Subsystem Functions(Simulink Coder). For examples of generated subsystem function code, seeModular Function Code for Nonvirtual Subsystems.

Modular Function Code for Nonvirtual Subsystems

To illustrate the selection of the傅nction with separate data选择nonvirtual子系统,下面的procedure generates atomic subsystem function code with and without the option selected and compares the results.

  1. Open MATLAB®and open the modelrtwdemo_atomicusing the MATLAB commandrtwdemo_atomic.

    Examine the Simulink model. This model shows how to preserve the boundary of a virtual subsystem. By selecting the Subsystem Parameters optionTreat as atomic unit, you guarantee that the code for that subsystem executes as an atomic unit. When a system is marked as atomic, you can specify how the subsystem is represented in code with the Subsystem Parameters optionCode Generation Function Packaging. You can specify that the subsystem is translated to any of the following types of implementation:

    • Inline: Inline the subsystem code at the call sites

    • 傅nction: A void/void function with I/O and internal data in global data structure

    • Reusable Function: A reentrant function with data passed in as part of function arguments

    • Auto: Let the code generator optimize the implementation based on context

  2. Double-click the SS1 subsystem and examine the contents.

    Close the subsystem window when you are finished.

  3. Right-click the SS1 subsystem, select Block Parameters (Subsystem) from the context menu, and examine the settings. Simulink and the code generator can avoid "artificial" algebraic loops when the subsystem is made atomic with the subsystem optionMinimize algebraic loop occurrences.

    Close the Block Parameters dialog box when you are finished.

  4. Change theSystem target filefor the mode fromgrt.tlctoert.tlc. Select theConfiguration Parameters>Code Generationtab and specifyert.tlcfor theSystem target fileparameter. ClickOKtwice to confirm the change. Using the ERT target provides more code generation options for the atomic subsystem.

  5. Create a variant ofrtwdemo_atomicthat illustrates function codewithoutdata separation.

    1. In thertwdemo_atomicmodel, right-click the SS1 subsystem and selectBlock Parameters (Subsystem). In the Subsystem Parameters dialog box that appears, verify that

      • On theMaintab,Treat as atomic unitis selected

      • On theCode Generationtab,User specifiedis selected for傅nction name options

      • On theCode Generationtab,myfunis specified for傅nction name

    2. In the Subsystem Parameters dialog box, on theCode Generationtab verify that

      1. Nonreusable functionis selected for the傅nction packagingparameter. After this selection, additional parameters and options appear.

      2. Use function nameis selected for theFile name optionsparameter. This selection is optional but simplifies the later task of code comparison by causing the atomic subsystem function code to be generated into the filesmyfun.candmyfun.h.

      Donotselect the option傅nction with separate data. ClickApplyto apply the changes and clickOKto exit the dialog box.

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

  6. Create a variant ofrtwdemo_atomicthat illustrates function codewithdata separation.

    1. In thertwdemo_atomic1model (orrtwdemo_atomicwith step 3 reapplied), right-click the SS1 subsystem and selectBlock Parameters (Subsystem). In the Subsystem Parameters dialog box, verify that

      • On theMaintab,Treat as atomic unitis selected

      • On theCode Generationtab,傅nctionis selected for傅nction packaging

      • On theCode Generationtab,User specifiedis selected for傅nction name options

      • On theCode Generationtab,myfunis specified for傅nction name

      • On theCode Generationtab,Use function nameis specified forFile name options

    2. In the Subsystem Parameters dialog box, on theCode Generationtab, select the option傅nction with separate data. ClickApplyto apply the change and clickOKto exit the dialog box.

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

  7. Generate code for each model,rtwdemo_atomic1andrtwdemo_atomic2.

  8. In the generated code directories, compare themodel.c/.handmyfun.c/.hfiles generated for the two models. For code comparison discussion, seeH File Differences for Nonvirtual Subsystem Function Data SeparationandH File Differences for Nonvirtual Subsystem Function Data SeparationC File Differences for Nonvirtual Subsystem Function Data Separation.

    In this example, there are not significant differences in the generated variants ofert_main.c,model_private.h,model_types.h, orrtwtypes.h.

H File Differences for Nonvirtual Subsystem Function Data Separation

The differences between the H files generated forrtwdemo_atomic1andrtwdemo_atomic2help illustrate the selection of the傅nction with separate dataoption for nonvirtual subsystems.

  1. Selecting傅nction with separate datacausestypedefs for subsystem data to be generated in themyfun.hfile forrtwdemo_atomic2:

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

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

    /* Block signals (auto storage) */ typedef struct { ... real_T Integrator; /* '/Integrator' */ } BlockIO_rtwdemo_atomic1; /* Block states (auto storage) for system '' */ typedef struct { real_T Integrator_DSTATE; /* '/Integrator' */ } D_Work_rtwdemo_atomic1;
  2. Selecting傅nction with separate datagenerates the following external declarations in themyfun.hfile forrtwdemo_atomic2:

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

    By contrast, the generated code forrtwdemo_atomic1contains model-level external declarations for the subsystem'sBlockIOandD_Workdata, inrtwdemo_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 forrtwdemo_atomic1andrtwdemo_atomic2illustrate the selection of the傅nction with separate dataoption for nonvirtual subsystems.

  1. Selecting傅nction with separate datacauses a separate subsystem initialize function,myfun_initialize, to be generated in themyfun.cfile forrtwdemo_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 inmyfun.cis invoked by the model initialize function inrtwdemo_atomic2.c:

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

    By contrast, forrtwdemo_atomic1initi、子系统初始化的数据模型alize function inrtwdemo_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傅nction with separate datagenerates the following declarations in themyfun.cfile forrtwdemo_atomic2:

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

    By contrast, the generated code forrtwdemo_atomic1contains model-level declarations for the subsystem'sBlockIOandD_Workdata, inrtwdemo_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傅nction with separate datagenerates identifier naming that reflects the subsystem orientation of data items. Notice the references to subsystem data in subsystem functions such asmyfunandmyfun_updateor in the model'smodel_stepfunction. For example, compare this code frommyfunforrtwdemo_atomic2

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

    to the corresponding code frommyfunforrtwdemo_atomic1.

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

Nonvirtual Subsystem Modular Function Code Limitations

The nonvirtual subsystem option傅nction with separate datahas the following limitations:

  • The傅nction with separate dataoption is available only in ERT-based Simulink models (requires a Embedded Coder license).

  • The nonvirtual subsystem to which the option is applied cannot have multiple sample times or continuous sample times; that is, the subsystem must be single-rate with a discrete sample time.

  • The nonvirtual subsystem cannot contain continuous states.

  • The nonvirtual subsystem cannot output function call signals.

  • The nonvirtual subsystem cannot contain noninlined S-functions.

  • The generated files for the nonvirtual subsystem will reference model-wide header files, such asmodel.handmodel_private.h.

  • The傅nction with separate dataoption is incompatible with theClassic call interfaceoption, located on theCode Generation>Interfacepane of the Configuration Parameters dialog box. Selecting both generates an error.

  • The傅nction with separate dataoption is incompatible with settingCode interface packagingtoReusable function(Code Generation>Interfacepane). Selecting both generates an error.

  • When you select傅nction with separate datafor a subsystem, the model that contains the subsystem cannot contain aData Store Memoryblock withShare across model instancesselected. SeeData Store Memory.

Related Topics

Was this topic helpful?