Configure Data Interface in the Generated Code

Specify signals, states, and parameters for inclusion in generated code.

Learn how to control these attributes of data in the generated code:

  • Name

  • Data type

  • Data storage class

For information about the example model and other examples in this series, see Generate C Code from a Control Algorithm for an Embedded System.

Open Example Model

Open the example model, rtwdemo_PCG_Eval_P2.


Data Declaration

Most programming languages require that you declare data and functions before using them. The declaration specifies:

  • Scope: The region of the program that has access to the data

  • Duration: The period during which the data exist in memory

  • Data type: The amount of memory allocated for the data

  • Initialization: A value, a pointer to memory, or NULL

The combination of scope and duration is the storage class. If you do not provide an initial value, most compilers assign a zero value or a null pointer.

Supported data types include:

  • double: Double-precision floating point

  • single: Single-precision floating point

  • int8: Signed 8-bit integer

  • uint8: Unsigned 8-bit integer

  • int16: Signed 16-bit integer

  • uint16: Unsigned 16-bit integer

  • int32: Signed 32-bit integer

  • uint32: Unsigned 32-bit integer

  • Fixed Point: 8-, 16-, 32-bit word lengths

With storage classes and custom storage classes, you can:

  • Generate exported files, with custom names, that contain global variable declarations and definitions.

  • Import custom header files that contain global variable declarations.

  • Generate const or volatile type qualifiers in declarations.

  • Represent a parameter as a macro (#define or compiler option).

  • Package signals or parameters into flat structures or bit fields.

Control Data in Simulink® and Stateflow®

This example uses data objects to specify code generation settings for data. Alternatively, you can store the settings in the model by using dialog boxes. Both methods allow full control over the data type and storage class. You can use both methods in a single model.

This example focuses on these types of data objects:

  • Signal

  • Parameter

  • Bus

The code generator uses the objects from the MATLAB base workspace or a Simulink data dictionary. You can create and inspect the objects with commands at the command prompt or in the Model Explorer.

As an example, inspect the definition of the Simulink.Signal object pos_cmd_one, which the model created in the base workspace:

pos_cmd_one = 

  Signal with properties:

         CoderInfo: [1×1 Simulink.CoderInfo]
       Description: 'Throttle position command from the first PI controller'
          DataType: 'double'
               Min: -1
               Max: 1
              Unit: ''
        Dimensions: -1
    DimensionsMode: 'auto'
        Complexity: 'auto'
        SampleTime: -1
      InitialValue: '0'

You can open the Model Explorer and display details about a specific data object in the example model.

Open the Model Explorer.


In the Model Hierarchy pane, select Base Workspace. In the Contents pane, inspect the definitions of these objects:

  • pos_cmd_one: Top-level output, Double, Exported Global

  • pos_rqst: Top-level input, Double, Imported Extern Pointer

  • P_InErrMap: Calibration parameter, Auto, Constant

  • ThrotComm (1): Top-level output structure, Auto, Exported Global

  • ThrottleCommands (1): Bus definition, Struct, None

(1) ThrottleCommands defines a Simulink.Bus object. ThrotComm is a bus signal, which is an instantiation of ThrottleCommands. If a bus signal is nonvirtual, the signal appears as a structure in the C code.

As in C, you can use a bus definition (ThrottleCommands) to create multiple instances of the structure. In a model diagram, a bus signal appears as a wide line with central dashes.

A data object has properties that you configure for simulation and for code generation, including:

  • DataType (numeric data type for storage in the generated code)

  • StorageClass (storage class for code generation)

  • Value (parameter value)

  • InitialValue (initial value for signal)

  • Alias (alternative name for the data, which the code generator uses)

  • Dimensions (size and number of dimensions of parameter or signal value)

  • Complexity (numeric complexity)

  • Unit (physical units such as cm)

  • Min (minimum value)

  • Max (maximum value)

Use the property Description to specify custom documentation for data objects.

Add New Data Objects

You can create data objects for named signals, states, and parameters. To associate a data object with a construct, the construct must have a name.

The Data Object Wizard tool finds constructs for which you can create data objects, and then creates the objects for you. The example model includes two signals that are not associated with data objects: fbk_1 and pos_cmd_two.

To find the signals and create data objects for them:

1. Open the Data Object Wizard.


2. Click Find to find candidate constructs.

3. Click Select All to select all candidates.

4. Click Create to create the data objects.

The Data Object Wizard performs the equivalent of the following commands:

fbk_1 = Simulink.Signal;
fbk_1.Dimensions = 1;
fbk_1.DataType = 'double';
outport = get_param('rtwdemo_PCG_Eval_P2/fbk_1','PortHandles');
outport = outport.Outport;

pos_cmd_two = Simulink.Signal;
pos_cmd_two.Dimensions = 1;
pos_cmd_two.DataType = 'double';
outport = get_param('rtwdemo_PCG_Eval_P2/PI_ctrl_2','PortHandles');
outport = outport.Outport;

Configure Data Objects

Set the data type and storage class for each data object. To configure data object properties, in the Model Explorer Contents pane, click an object. You can edit the properties by using the corresponding columns in the Contents pane, or edit the properties in the Dialog pane.

Use the Model Explorer to configure these data object properties:

  • fbk_1: Data type double, storage class ImportedExtern

  • pos_cmd_two: Data type double, storage class ExportedGlobal

Alternatively, you can use these commands to configure the objects:

fbk_1.DataType = 'double';
fbk_1.StorageClass = 'ImportedExtern';

pos_cmd_two.DataType = 'double';
pos_cmd_two.StorageClass = 'ExportedGlobal';

Control File Placement of Parameter Data

With Embedded Coder®, you can control the file placement of definitions for parameters and constants. The example model writes all parameter definitions to the file eval_data.c.

To change the placement of parameter and constant definitions, set the data placement options for the model configuration. In the Configuration Parameters dialog box, configure the options on the Code Generation > Code Placement pane.

In the example model, inspect the Code Placement pane in the Configuration Parameters dialog box. The model places data definitions in the file eval_data.c and declarations in the file eval_data.h.

Declare Block Parameters Tunable or Inlined

You can control the default tunability of block parameters in the generated code. In the Configuration Parameters dialog box, on the Optimization > Signals and Parameters pane, adjust the setting for Default parameter behavior.

For the example model, the default parameter behavior is set to Inlined. By default, block parameters appear in the code as numeric literal values, not as variables stored in memory. You can use Simulink.Parameter objects to override inlining and preserve tunability for individual parameters.

Enable Signal Data Objects in Generated Code

Make sure that the signal data objects (Simulink.Signal) appear in the generated code. For individual signal lines in the model, set the option Signal name must resolve to Simulink signal object to explicitly resolve the signal name to a Simulink.Signal object in a workspace or data dictionary.

1. Right-click the signal line.

2. Select Properties.

3. In the Signal Properties dialog box, make sure that the option Signal name must resolve to Simulink signal object is selected.

You can manually select this option for individual signal lines. Alternatively, you can select the option for all such signals in a model. At the command prompt, use the disableimplicitsignalresolution function.

View Data Objects in Generated Code

Generate code from the example model.

### Starting build procedure for model: rtwdemo_PCG_Eval_P2
### Successful completion of code generation for model: rtwdemo_PCG_Eval_P2

Create a code generation report to more easily view the generated files. In the Simulink Editor, select Code > C/C++ Code > Code Generation Report > Open Model Report.

You can access these generated files:

  • rtwdemo_PCG_Eval_P2.c: Defines the step and initialization functions. Uses the defined data objects.

  • eval_data.c: Assigns initial values to the defined parameters. The model configuration specifically sets the file name.

  • eval_data.h: Provides extern declarations of parameter data. The model configuration specifically sets the file name.

  • ert_main.c: Defines scheduling functions.

  • rtwdemo_PCG_Eval_P2.h: Contains the type definitions of the default structures that store signal, state, and parameter data. Due to the data object settings, some data appear in eval_data.c instead.

  • PCG_Eval_p2_private.h: Declares private (local) data for the generated functions.

  • rtwdemo_PCG_Eval_P2_types.h: Declares the real-time model data structure.

  • rtwtypes.h: Provides mapping to the data types that Simulink® Coder™ defines (typedef). Used for integration with external systems.

For example, view the file eval_data.c, which allocates const memory for global variables that correspond to the Simulink.Parameter objects in the base workspace.

cfile = fullfile('rtwdemo_PCG_Eval_P2_ert_rtw','eval_data.c');
rtwdemodbtype(cfile,'/* Exported data definition */','* [EOF]',1,1)
/* Exported data definition */

/* Const memory section */
/* Definition for custom storage class: Const */
const real_T I_Gain = -0.03;
const real_T I_InErrMap[9] = { -1.0, -0.5, -0.25, -0.05, 0.0, 0.05, 0.25, 0.5,
  1.0 } ;

const real_T I_OutMap[9] = { 1.0, 0.75, 0.6, 0.0, 0.0, 0.0, 0.6, 0.75, 1.0 } ;

const real_T P_Gain = 0.74;
const real_T P_InErrMap[7] = { -1.0, -0.25, -0.01, 0.0, 0.01, 0.25, 1.0 } ;

const real_T P_OutMap[7] = { 1.0, 0.25, 0.0, 0.0, 0.0, 0.25, 1.0 } ;

 * File trailer for generated code.
 * [EOF]

View the code algorithm in the model step function in the file rtwdemo_PCG_Eval_P2.c. The algorithm uses the data object names directly.

cfile = fullfile('rtwdemo_PCG_Eval_P2_ert_rtw','rtwdemo_PCG_Eval_P2.c');
rtwdemodbtype(cfile,'/* Model step function */',...
    '/* Sum: ''<S2>/Sum3'' incorporates:',1,0);
/* Model step function */
void rtwdemo_PCG_Eval_P2_step(void)
  real_T rtb_IntegralGainShape;
  real_T Discrete_Time_Integrator1;
  real_T Discrete_Time_Integrator1_i;

  /* Sum: '<S2>/Sum2' incorporates:
   *  Inport: '<Root>/fbk_1'
   *  Inport: '<Root>/pos_rqst'
  rtb_IntegralGainShape = *pos_rqst - fbk_1;

  /* DiscreteIntegrator: '<S2>/Discrete_Time_Integrator1' incorporates:
   *  Gain: '<S2>/Int Gain1'
   *  Lookup_n-D: '<S2>/Integral  Gain Shape'
   *  Product: '<S2>/Product3'
  Discrete_Time_Integrator1 = I_Gain * look1_binlx(rtb_IntegralGainShape,
    (&(I_InErrMap[0])), (&(I_OutMap[0])), 8U) * rtb_IntegralGainShape * 0.001 +

Without storage classes and other code generation settings that the data objects specify, the generated code:

  • Inlines invariant signals and block parameters when you select these optimizations in the model configuration parameters

  • Places model input and output signals, block states, and tunable parameters in global data structures

  • Does not create global variables that correspond to MATLAB® variables

In contrast, the example code shows that most of the default data structures have been replaced with user-defined data objects. For example, these signals and parameters appear as global variables in the code:

  • pos_rqst

  • fbk_1

  • I_Gain

  • I_OutMap

  • I_InErrMap

However, the local variable rtb_IntegralGainShape and the state variable rtwdemo_PCG_Eval_P2_DWork.Discrete_Time_Integrator1_DSTAT still use the Simulink® Coder™ data structures. Data objects do not exist for these entities.

Store Model Data in Data Dictionary

When you end your MATLAB session, variables that you create in the base workspace do not persist. To permanently store data objects and bus objects, consider linking the model to a data dictionary.

  1. In the example model, select File > Model Properties > Link to Data Dictionary.

  2. In the Model Properties dialog box, select Data Dictionary. Click New.

  3. In the Create a new Data Dictionary dialog box, set File name to rtwdemo_PCG_Eval_dict and click Save. In the Model Properties dialog box, click OK.

  4. Click Yes in response to the message about migrating base workspace data. Click Yes in response to the message about removing the imported items from the base workspace.

Alternatively, to manually migrate the objects into a data dictionary, you can use programmatic commands:

% Create a list of the variables and objects that the target
% model uses.
usedVars = {Simulink.findVars('rtwdemo_PCG_Eval_P2').Name};
% Create a new data dictionary in your current folder. Link the model to
% this new dictionary.
dictObj ='rtwdemo_PCG_Eval_dict.sldd');
% Import only the target variables from the base workspace to the data
% dictionary.

The data dictionary now permanently stores the objects that the model uses. To view the contents of the dictionary, click the data dictionary badge in the lower-left corner of the model.

The separation of data from the model provides these benefits:

One model, multiple data sets

  • Use of different data types to change the targeted hardware (for example, for floating-point and fixed-point targets)

  • Use of different parameter values to change the behavior of the control algorithm (for example, for reusable components with different calibration values)

Multiple models, one data set

  • Sharing of data between Simulink® models in a system

  • Sharing of data between projects (for example, transmission, engine, and wheel controllers might all use the same CAN message data set)

For the next example in this series, see Partition Functions in the Generated Code.

More About

Was this topic helpful?