This example shows how to specify signals and parameters for inclusion in generated code.
Time: 45 minutes
Learn how to control the following attributes of signals and parameters in the generated code:
Data storage class
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 is resident 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
Supported storage classes include:
Name Description Parameters Signals Data Supported Supported Types
Const Use const type qualifier in declaration Y N All
ConstVolatile Use const volatile type qualifier in Y N All declaration
Volatile Use volatile type qualifier in declaration Y Y All
ExportToFile Generate and include files, with Y Y All user-specified name, containing global variable declarations and definitions
ImportFromFile Include predefined header files containing Y Y All global variable declarations
Exported Global Declare and define variables of global Y Y All scope
Imported Extern Import a variable that is defined outside Y Y All of the scope of the model
BitField Embed boolean data in a named bit field Y Y Boolean
Define Represent parameters with a #define macro Y N All
Struct Embed data in a named struct to Y Y All encapsulate sets of data
Two methods are available for declaring data in Simulink and Stateflow: data objects and direct specification. This example uses the data object method. Both methods allow full control over the data type and storage class. You can mix the two methods in a single model.
You can use data objects in a variety of ways in the MATLAB and Simulink environment. The example focuses on three types of data objects.
The code generator uses data objects from the MATLAB base workspace. You can create and inspect them by entering commands in the MATLAB Command Window or by using the Model Explorer.
The following example shows the definition of Simulink signal object pos_cmd_one:
You can open the Model Explorer and display details about a specific data object in the example model.
Click each of the following object names:
(1) ThrottleCommands defines a Simulink Bus object, ThrotComm is the instantiation of the bus. If the bus is a nonvirtual bus, the signal will generate a structure in the C code.
As in C, you can use a bus definition (ThrottleCommands) to instantiate multiple instances of the structure. In a model diagram, a bus object appears as a wide line with central dashes, as shown below.
The following figure shows the Model Explorer display if you click the signal name pos_rqst:
A data object has a mixture of active and descriptive fields. Active fields affect simulation or code generation. Descriptive fields do not affect simulation or code generation, but are used with data dictionaries and model-checking tools.
Initial value (signals)
Alias (define a different name in the generated code)
Dimension (inherited for parameters)
Complexity (inherited for parameters)
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 is a tool that finds constructs for which you can create data objects, 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:
2. Click Find to find candidate constructs.
3. Click Select All to select all candidates.
4. Click Apply Package to apply the Simulink package for the data objects.
5. Click Create to create the data objects.
The next step is to set the data type and storage class.
1. Click the following object names to edit the data objects:
Clicking a name opens the Model Explorer to show the base workspace.
2. For each object listed in the preceding table, click the signal name in the Contents pane.
3. Change the field settings in the Data pane to match those in the table.
Note: If the Model Explorer does not open for either of the two signals, repeat the steps in Adding New Data Objects.
Embedded Coder allows you to control the files in which the parameters and constants are defined. For the example model, all parameters were written to the file eval_data.c.
To change the placement of parameter and constant definitions, set the appropriate data placement options for the model configuration. Within the Model Explorer, you set the options at Configuration > Code Generation > Data Placement. For the example, the model has already been configured.
2. Enter data in the Data Placement pane as shown in the following figure:
The generated code that results for eval_data.c is shown below.
The next step is to ensure that the data objects you have created appear in the generated code. To enable parameters in generated code, set the Inline parameters option for the model configuration. In the Model Explorer, this option is:
Configuration > Optimization > Signals and Parameters > Simulation and code generation > Inline parameters
To enable a signal in generated code:
1. Right-click the signal line.
2. From the context menu, select Signal Properties. A Signal Properties dialog box appears.
3. Make sure the option Signal name must resolve to a Simulink signal object is selected.
You can enable signals associated with data objects individually, or you can enable all such signals in a model at once by entering disableimplicitsignalresolution in the MATLAB Command Window.
For the example model, all data types are set to double. Since Simulink uses the double data type for simulation, no changes are expected in the model behavior when you run the generated code. To verify this, run the test harness model. The test harness model is automatically updated to include the rtwdemo_PCG_Eval_P2 model. That is the only change made to the test harness.
The resulting plot shows that the difference between the golden and simulated versions of the model remains zero.
Now view the file rtwdemo_PCG_Eval_P2.c to see how the use of data objects changed the generated code.
Click the following file names to view generated code:
The following figure shows the code for function rtwdemo_PCG_Eval_P2_step as it appears in rtwdemo_PCG_Eval_P2.c before the use of data objects:
The figure below shows the code as it appears in rtwdemo_PCG_Eval_P2.c with data objects.
This figure shows that most of the Simulink Coder™ data structures have been replaced with user-defined data objects. The local variable rtb_Sum2 and the state variable rtwdemo_PCG_Eval_P2_DWork.Discrete_Time_Integrator1_DSAT still use the Simulink Coder™ data structures.
Data objects exist in the MATLAB base workspace. They are saved in a separate file from the model. To save the data manually, enter save in the MATLAB Command Window.
The separation of data from the model provides many 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)