Skip to Main Content Skip to Search
Product Documentation

Export Code Generated from Model to External Application

Export Function-Call Subsystems

About Exporting Function-Call Subsystems

Embedded Coder software provides code export capabilities that you can use to

You can use these capabilities only if the subsystem and its interface to the Simulink model conform to certain requirements and constraints, as described in Requirements for Exporting Function-Call Subsystems. For limitations that apply, see Function-Call Subsystems Export Limitations.

Exported Subsystems Demo.  To see a demo of exported function-call subsystems, type rtwdemo_export_functions in the MATLAB Command Window.

Additional Information.  See the following in the Simulink documentation for additional information relating to exporting function-call subsystems:

If you want to use Stateflow blocks to trigger exportable function-call subsystems, you may also need information from the Stateflow User's Guide.

Requirements for Exporting Function-Call Subsystems

To be exportable as code, a function-call subsystem, or a virtual subsystem that contains such subsystems, must meet certain requirements. Most requirements are similar for either type of export, but some apply only to virtual subsystems. The requirements for all Simulink code generation also apply.

For brevity, exported subsystem in this section means only an exported function-call subsystem or an exported virtual subsystem that contains such subsystems. The requirements listed do not necessarily apply to other types of exported subsystems.

Requirements for All Exported Subsystems.  These requirements apply to both exported function-call subsystems and exported virtual subsystems that contain such subsystems.

Blocks Must Support Code Generation.  

All blocks within an exported subsystem must support code generation. However, blocks outside the subsystem need not support code generation unless they will be converted to code in some other context.

Blocks Must Not Use Absolute Time.  

Certain blocks use absolute time. Blocks that use absolute time are not supported in exported function-call subsystems. For a complete list of such blocks, see Limitations on the Use of Absolute Time in the Simulink Coder documentation.

Blocks Must Not Depend on Elapsed Time.  

Certain blocks, like the Sine Wave block and Discrete Integrator block, depend on elapsed time. If an exported function-call subsystem contains any blocks that depend on elapsed time, the subsystem must specify periodic execution. See Export Function-Call Subsystems That Depend on Elapsed Time in the Simulink Coder documentation.

Trigger Signals Require a Common Source.  

If more than one trigger signal crosses the boundary of an exported system, all of the trigger signals must be periodic and originate from the same function-call initiator.

Trigger Signals Must Be Scalar.  

A trigger signal that crosses the boundary of an exported subsystem must be scalar. Input and output data signals that do not act as triggers need not be scalar.

Data Signals Must Be Nonvirtual.  

A data signal that crosses the boundary of an exported system cannot be a virtual bus, and cannot be implemented as a Goto-From connection. Every data signal crossing the export boundary must be scalar, muxed, or a nonvirtual bus.

Requirements for Exported Virtual Subsystems.  These requirements apply only to exported virtual subsystems that contain function-call subsystems.

Virtual Subsystem Must Use Only Permissible Blocks.  

The top level of an exported virtual subsystem that contains function-call subsystem blocks can contain only the following other types of blocks:

These restrictions do not apply within function-call subsystems, whether or not they appear in a virtual subsystem. They apply only at the top level of an exported virtual subsystem that contains one or more function-call subsystems.

Constant Blocks Must Be Inlined.  

When a constant block appears at the top level of an exported virtual subsystem, the containing model must check Inline parameters on the Optimization > Signals and Parameters pane of the Configuration Parameters dialog box.

Constant Outputs Must Specify a Storage Class.  

When a constant signal drives an output port of an exported virtual subsystem, the signal must specify a storage class.

Techniques for Exporting Function-Call Subsystems

General Workflow.  To export a function-call subsystem, or a virtual subsystem that contains function-call subsystems,

  1. Check that the subsystem to be exported satisfies the Requirements for Exporting Function-Call Subsystems.

  2. In the Configuration Parameters dialog box:

    1. On the Code Generation pane, specify an ERT code generation target such as ert.tlc.

    2. If you want a SIL block with the generated code, go to the SIL and PIL Verification pane and, from the Create block drop-down list, select SIL.

    3. Click OK or Apply.

  3. Right-click the subsystem block and choose Code Generation > Export Functions from the context menu.

    The Build code for subsystem: Subsystem dialog box appears. This dialog box is not specific to exporting function-call subsystems, and generating code does not require entering information in the box.

  4. Click Build.

    The MATLAB Command Window displays messages similar to those for any code generation sequence. Simulink generates code and places it in the working folder.

    If you set Create block to SIL in step 2b, Simulink opens a new window that contains an S-function block that represents the generated code. This block has the same size, shape, and connectors as the original subsystem.

Code generation and optional block creation are now complete. You can test and use the code and optional block as you could any generated ERT code and S-function block.

Specify a Custom Initialize Function Name.  You can specify a custom name for the initialize function of your exported function as an argument to the rtwbuild command. When used for this purpose, the command takes the following form:

blockHandle = rtwbuild('subsystem', 'Mode', 'ExportFunctionCalls',..
             'ExportFunctionInitializeFunctionName', 'fcnname')

where fcnname specifies the desired function name. For example, if you specify the name 'myinitfcn', the build process emits code similar to the following:

/* Model initialize function */
void myinitfcn(void){
...
}

Specify a Custom Description.  You can enter a custom description for an exported function using the Block Properties dialog box of an Inport block. To do this, go to the subsystem that is to be exported as a function, right-click on the Inport block that drives the control port of the subsystem, and select Block Properties. In the General tab, use the Description field to enter your descriptive text. During function export, the text you enter is emitted to the generated code in the header for the Inport block. For example, if you open the demo program rtwdemo_export_functions and enter a description in the Block Properties dialog box for port t_1tic_A, code similar to the following is emitted:

/* 
 * Output and update for exported function: t_1tic_A
 *
 *  My custom description of the exported function
*/
void t_1tic_A(void)
{
...
}

Optimize Exported Function-Call Subsystems

To optimize the code generated for a function-call subsystem or virtual block that contains such subsystems, you can

Export Function-Call Subsystems That Depend on Elapsed Time

Some blocks, such as the Sine Wave block (if sample-based) and the Discrete-Time Integrator block, depend on elapsed time. See Absolute and Elapsed Time Computation in the Simulink Coder documentation for more information.

When a block that depends on elapsed time exists in a function-call subsystem, the subsystem cannot be exported unless it specifies periodic execution. To specify for this:

  1. Right-click the trigger port block in the function-call subsystem and choose TriggerPort Parameters from the context menu.

  2. Specify periodic in the Sample time type field.

  3. Set the Sample time to the same granularity specified (directly or by inheritance) in the function-call initiator.

  4. Click OK or Apply.

Function-Call Subsystem Export Example

The next figure shows the top level of a model that uses a Stateflow chart named Chart to input two function-call trigger signals (denoted by dash-dot lines) to a virtual subsystem named Subsystem.

The next figure shows the contents of Subsystem in the previous figure. The subsystem contains two function-call subsystems, each driven by one of the signals input from the top level.

In the preceding model, the Stateflow chart can assert either of two scalar signals, Toggle and Select.

The following generated code implements the subsystem named Subsystem. The code is typical for virtual subsystems that contain function-call subsystems. It specifies an initialization function and a function for each contained subsystem, and would also include functions to enable and disable subsystems if applicable.

#include "Subsystem.h"
#include "Subsystem_private.h"
   
/* Exported block signals */
real_T DataIn1;                         /* '<Root>/In3' */
real_T DataIn2;                         /* '<Root>/In4' */
real_T DataOut;                         /* '<S4>/Switch' */
boolean_T SelectorSignal;               /* '<S5>/Logical Operator' */
   
/* Exported block states */
boolean_T SelectorState;                /* '<S5>/Unit Delay' */
   
/* Real-time model */
RT_MODEL_Subsystem Subsystem_M_;
RT_MODEL_Subsystem *Subsystem_M = &Subsystem_M_;
  
/* Initial conditions for exported function: Toggle */
  
void Toggle_Init(void)
{
  /* Initial conditions for function-call system: '<S1>/Toggle Output Subsystem' */
   
  /* InitializeConditions for UnitDelay: '<S5>/Unit Delay' */
  SelectorState = Subsystem_P.UnitDelay_X0;
}
   
/* Output and update for exported function: Toggle */
  
void Toggle(void)
{
  /* Output and update for function-call system: '<S1>/Toggle Output Subsystem' */
   
  /* Logic: '<S5>/Logical Operator' incorporates:
   *  UnitDelay: '<S5>/Unit Delay'
   */
  SelectorSignal = !SelectorState;
   
  /* Update for UnitDelay: '<S5>/Unit Delay' */
  SelectorState = SelectorSignal;
}
    
/* Output and update for exported function: Select */
    
void Select(void)
{
  /* Output and update for function-call system: '<S1>/Select Input Subsystem' */
     
  /* Switch: '<S4>/Switch' incorporates:
   *  Inport: '<Root>/In3'
   *  Inport: '<Root>/In4'
   */
  if(SelectorSignal) {
    DataOut = DataIn1;
  } else {
    DataOut = DataIn2;
  }
}
      
/* Model initialize function */
     
void Subsystem_initialize(void)
{
  /* initialize error status */
  rtmSetErrorStatus(Subsystem_M, (const char_T *)0);
     
  /* block I/O */
     
  /* exported global signals */
  DataOut = 0.0;
  SelectorSignal = FALSE;
    
  /* states (dwork) */
      
  /* exported global states */
  SelectorState = FALSE;
      
  /* external inputs */
  DataIn1 = 0.0;
  DataIn2 = 0.0;
      
  Toggle_Init();
}
     
/* Model terminate function */
     
void Subsystem_terminate(void)
{
  /* (no terminate code required) */
}

Function-Call Subsystems Export Limitations

The function-call subsystem export capabilities have the following limitations:

Control Generation of Function Prototypes

The Embedded Coder software provides a Configure Model Functions button, located on the Code Generation > Interface pane of the Configuration Parameters dialog box, that allows you to control the model function prototypes that are generated for ERT-based Simulink models.

By default, the function prototype of an ERT-based model's generated model_step function resembles the following:

void model_step(void);

The function prototype of an ERT-based model's generated model_init function resembles the following:

void model_init(void);

(For more detailed information about the default calling interface for the model_step function, see the model_step reference page.)

The Configure Model Functions button on the Interface pane provides you flexible control over the model function prototypes that are generated for your model. Clicking Configure Model Functions launches a Model Interface dialog box. Based on the Function specification value you specify for your model function (supported values include Default model initialize and step functions and Model specific C prototypes), you can preview and modify the function prototypes. Once you validate and apply your changes, you can generate code based on your function prototype modifications.

For more information about using the Configure Model Functions button and the Model Interface dialog box, see Function Prototype Control Example and the demo model rtwdemo_fcnprotoctrl, which is preconfigured to demonstrate function prototype control.

Alternatively, you can use function prototype control functions to programmatically control model function prototypes. For more information, see Configure Function Prototypes ProgrammaticallyConfigure Function Prototypes Programmatically.

You can also control model function prototypes for nonvirtual subsystems, if you generate subsystem code using right-click build. To launch the Model Interface for subsystem dialog box, use the RTW.configSubsystemBuild function.

Right-click building the subsystem generates the step and initialization functions according to the customizations you make. For more information, see Configure Function Prototypes for Nonvirtual Subsystems.

For limitations that apply, see Function Prototype Control Limitations.

C++ Encapsulation Interface Control

Using the Language option, C++ (Encapsulated), on the Code Generation pane of the Configuration Parameters dialog box, you can generate a C++ class interface to model code. The generated interface encapsulates all required model data into C++ class attributes and all model entry point functions into C++ class methods. The benefits of encapsulation include:

C++ encapsulation also works for right-click builds of nonvirtual subsystems. (For information on requirements that apply, see Configure C++ Encapsulation Interfaces for Nonvirtual Subsystems.)

The general procedure for generating C++ encapsulation interfaces to model code is as follows:

  1. Configure your model to use an ert.tlc system target file provided by MathWorks.

  2. Select the language option C++ (Encapsulated) for your model.

  3. Optionally, configure related C++ encapsulation interface settings for your model code, using either a graphical user interface (GUI) or application programming interface (API).

  4. Generate model code and examine the results.

To get started with an example, see C++ Encapsulation Quick-Start Example. For more details about configuring C++ encapsulation interfaces for your model code, see Generating and Configuring C++ Encapsulation Interfaces to Model Code and Configure C++ Encapsulation Interfaces Programmatically. For limitations that apply, see C++ Encapsulation Interface Control 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