Organize Data into Structures in Generated Code
In C code, you use structures (struct
) to store data in contiguous locations in memory. You can organize data, such as signals and states, by using meaningful names. Each structure acts as a namespace, so you can reuse a name to designate multiple data items. Like arrays, with structures, you can write code that efficiently transfers and operates on large amounts of data by using pointers.
By default, the code generator aggregates data into standard structures (see如何生成的代码存储内部信号,状态,and Parameter Data). To control the characteristics of these structures or to override this default behavior by creating different structures, use the information in the table.
Goal | Technique |
---|---|
Control the characteristics of the standard data structures. For example, specify the names of the structure types, structure variables, and field names. |
With Embedded Coder®, seeControl Characteristics of Data Structures (Embedded Coder)(Embedded Coder). |
Control the placement of the structures in memory, for example, by inserting pragmas or other code decorations. |
With Embedded Coder, seeControl Data and Function Placement in Memory by Inserting Pragmas(Embedded Coder). |
Aggregate data into structures whose names and other basic characteristics you can control. As you add blocks and signals to the model, the resulting new data appears in these structures by default. |
With Embedded Coder, apply a structured storage class to a category of data by using the Code Mapping Editor.
For more information about the Code Mapping Editor, seeConfigure Default C Code Generation for Categories of Model Data and Functions(Embedded Coder). To create your own storage class, seeDefine Storage Classes, Memory Sections, and Function Templates for Software Architecture(Embedded Coder). |
Improve readability of the generated code by organizing individual data items into a custom structure whose characteristics you can finely control. |
Create a
To create an array of structures, seeArrays of Structures. |
Exchange structured data between generated code and your external code, for example, when the external code already defines a custom structure type and a corresponding global variable. |
Create a |
Reduce the number of arguments (formal parameters) for generated functions. |
|
Organize lookup table data into a structure. |
UseSimulink.LookupTable andSimulink.Breakpoint objects. SeeSimulink.LookupTable . |
Generate bit fields. | SeeBitfields(Embedded Coder) andOptimize Generated Code By Packing Boolean Data Into Bitfields(Embedded Coder). |
Techniques to Create Structures
To create structures in the generated code, you can use these techniques:
Apply a structured storage class to categories of data by using the Code Mapping Editor. As you add blocks and signals to a model, new data elements acquire this storage class by default.
Apply a structured storage class, such as the built-in storage class
Struct
, directly to individual data items by using the Model Data Editor.Create custom nonvirtual buses and parameter structures.
To decide which techniques to use, use the information in the table.
Capability | Default Application of Structured Storage Class | Direct Application of Structured Storage Class | Nonvirtual Buses and Parameter Structures |
---|---|---|---|
Aggregate new data items into a structure by default | Yes |
No | No |
Prevent elimination of the target data by optimizations (specify that the data appear in the generated code) | No |
Yes | Only if you directly apply a storage class such asExportedGlobal to the bus or structure |
Aggregate data into a structure without changing the appearance of the block diagram | Yes |
Yes | No |
Place signal, state, and parameter data in the same structure | No | Yes | No |
Include state data in a structure | Yes | Yes | No |
Organize structures into nested structures | No | No | Yes |
Organize structures into an array of structures | No | No | Yes |
Control name of structure type | Yes |
Yes, but the type name derives from the variable name, which you specify | Yes |
Create a structure to reduce the number of arguments in a generated function | Yes, but you must create your own storage class by using an Embedded Coder Dictionary |
No | Yes |
Requires Embedded Coder | Yes | Yes | No |
Default Application of Structured Storage Class
You can apply a default storage class to a category of model data. As you add blocks and signals to the model, the associated data acquire the default storage class that you specify. To aggregate new data into structures by default, you can apply structured storage classes. You must use example storage classesParamStruct
andSignalStruct
created by the Quick Start tool or create your own storage class by using an Embedded Coder Dictionary.
You cannot use default application to aggregate global data stores or global parameters (parameter objects that you store in the base workspace or a data dictionary).
To apply default storage classes, use the Code Mapping Editor. In a model window, in the Apps gallery, clickEmbedded Coder. Then, underCode Mappings>Data Defaults, apply storage classes by using theStorage Classcolumn.
For more information about the Code Mapping Editor, seeConfigure Default C Code Generation for Categories of Model Data and Functions(Embedded Coder). To create your own storage class by using an Embedded Coder Dictionary, seeCreate Code Definitions for Use as Default Code Generation Settings(Embedded Coder).
Direct Application of Structured Storage Class
You can apply a structured storage class to individual data items. The direct application prevents code generation optimizations, such asDefault parameter behaviorandSignal storage reuse, from eliminating each data item from the generated code. The direct application also overrides the default storage classes that you specify withCode Mappings>Data Defaults.
To directly apply a storage class, use the Model Data Editor (on theModelingtab, clickModel Data Editor). SetChange viewtoCode
and apply the storage class by using theStorage Classcolumn.
For an example that shows how to useStruct
, seeOrganize Parameter Data into a Structure by Using the Struct Storage Class(Embedded Coder). For more information about applying storage classes, seeApply Built-In and Customized Storage Classes to Data Elements(Embedded Coder).
Nonvirtual Buses and Parameter Structures
To create a nonvirtual bus signal, use aBus Creatorblock to organize multiple signal lines into a single bus, or configure anInportblock orOutportblock as a nonvirtual bus. You must create a
Simulink.Bus
object that represents the structure type. For an example, seeStructures of Signals. For general information about nonvirtual buses, seeGetting Started with Buses(Simulink).To create a parameter structure, use MATLAB®commands or the Variable Editor to organize the values of multiple block parameters into a MATLAB structure. Optionally, create a
Simulink.Bus
object so that you can control the name of the structure type and other characteristics such as the data type and dimensions of each field. For an example, seeStructures of Parameters. For general information about parameter structures, seeOrganize Related Block Parameter Definitions in Structures(Simulink).
Structures of Parameters
Create a structure in the generated code. The structure stores parameter data.
C Construct
typedef struct { double G1; double G2; } myStructType; myStructType myStruct = { 2.0, -2.0 } ;
Procedure
1. Open the example modelrtwdemo_paraminline
.
2. On theModelingtab, clickModel Data Editor. In the Model Data Editor, select theParameterstab.
3. In the model, click the Gain block labeledG1
. In the Model Data Editor, use theValuecolumn to set the value of theGainparameter tomyStruct.G1
.
4. Set the value of theGainparameter in theG2
block tomyStruct.G2
.
5. Next tomyStruct.G2
, click the action button (with three vertical dots) and selectCreate.
6. In the Create New Data dialog box, setValuetoSimulink.Parameter(struct)
and clickCreate. ASimulink.Parameter
object namedmyStruct
appears in the base workspace.
7. In the Simulink.Parameter property dialog box, next to theValueproperty, click the action button and selectOpen Variable Editor.
8. Right-click the white space under theFieldcolumn and selectNew. Name the new structure fieldG1
. Use theValuecolumn to set the value of the field to2
.
9. Add a fieldG2
whose value is-2
, and then close the Variable Editor.
10. In the Simulink.Parameter property dialog box, setStorage classtoExportedGlobal
. The structuremyStruct
appears in the generated code as a global variable.
11. Generate code from the model.
Results
The generated header filertwdemo_paraminline_types.h
defines a structure type that has a random name.
typedef struct { real_T G1; real_T G2; } struct_6h72eH5WFuEIyQr5YrdGuB;
The source filertwdemo_paraminline.c
defines and initializes the structure variablemyStruct
.
/* Exported block parameters */ struct_6h72eH5WFuEIyQr5YrdGuB myStruct = { 2.0, -2.0 } ; /* Variable: myStruct * Referenced by: * '/G1' * ' /G2' */
Specify Name of Structure Type
1. Optionally, specify a name to use for the structure type definition (struct
). At the command prompt, use the functionSimulink.Bus.createObject
to create aSimulink.Bus
object that represents the structure type.
2. The default name of the object isslBus1
. Change the name by copying the object into a new MATLAB variable.
3. In the Model Data Editor, click theShow/refresh additional informationbutton.
4. In the data table, find the row that corresponds tomyStruct
. Use theData Typecolumn to set the data type ofmyStruct
toBus: myStructType
.
5. Generate code from the model.
The code generates the definition of the structure typemyStructType
并使用这种类型定义全局变量myStruct
.
myStructType myStruct = { 2.0, -2.0 } ; /* Variable: myStruct
Structures of Signals
This example shows how to create a structure of signal data in the generated code.
C Construct
typedef struct { double signal1; double signal2; double signal3; } my_signals_type;
Procedure
1. To represent a structure type in a model, create aSimulink.Bus
object. Use the object as the data type of bus signals in your model.
2. Create theex_signal_struct
model by using Gain blocks, a Bus Creator block, and a Unit Delay block. The Gain and Unit Delay blocks make the structure more identifiable in the generated code.
3. To configure the Bus Creator block to accept three inputs, in the block dialog box, setNumber of inputsto3
.
4. In the toolstrip, on theModelingtab, underDesign, clickBus Editor.
5. Use the Bus Editor to create aSimulink.Bus
object namedmy_signals_type
that contains three signal elements:signal1
,signal2
, andsignal3
. SeeCreate and Specify Bus Objects(Simulink).
This bus object represents the structure type that you want the generated code to use.
6. In the Bus Creator block dialog box, setOutput data typetoBus: my_signals_type
.
7. SelectOutput as nonvirtual bus. ClickOK. A nonvirtual bus appears in the generated code as a structure.
8. On theModelingtab, clickModel Data Editor. In the Model Data Editor, on theSignalstab, from theChange viewdrop-down list, selectCode
.
9. In the model, click the output signal of the Bus Creator block.
10. In the Model Data Editor, for the output of the Bus Creator block, setNametosig_struct_var
.
11. SetStorage ClasstoExportedGlobal
. The output of the Bus Creator block appears in the generated code as a separate global structure variable namedsig_struct_var
.
12. Generate code from the model.
Results
The generated header fileex_signal_struct_types.h
defines the structure typemy_signals_type
.
typedef struct { real_T signal1; real_T signal2; real_T signal3; } my_signals_type;
The source fileex_signal_struct.c
allocates memory for the global variablesig_struct_var
, which represents the output of the Bus Creator block.
/* Exported block signals */ my_signals_type sig_struct_var; /* '/Bus Creator' */
In the same file, in the modelstep
function, the algorithm accessessig_struct_var
and the fields ofsig_struct_var
.
嵌套结构的信号
You can create nested structures of signal data in the generated code.
C Construct
typedef struct { double signal1; double signal2; double signal3; } B_struct_type; typedef struct { double signal1; double signal2; } C_struct_type; typedef struct { B_struct_type subStruct_B; C_struct_type subStruct_C; } A_struct_type;
Procedure
To represent a structure type in a model, create aSimulink.Bus
object. Use the object as the data type of bus signals in your model.
To nest a structure inside another structure, use a bus object as the data type of a signal element in another bus object.
1. Create theex_signal_nested_struct
model with Gain blocks, Bus Creator blocks, and a Unit Delay block. The Gain and Unit Delay blocks make the structure more identifiable in the generated code.
2. To configure a Bus Creator block to accept three inputs, in the block dialog box, setNumber of inputsto3
.
3. In the toolstrip, on theModelingtab, underDesign, clickBus Editor.
Use the Bus Editor to create aSimulink.Bus
object namedA_struct_type
that contains two signal elements:subStruct_B
andsubStruct_C
. To create bus objects with the Bus Editor, seeCreate and Specify Bus Objects(Simulink). This bus object represents the top-level structure type that you want the generated code to use.
4. For thesubStruct_B
element, setDataTypetoBus: B_struct_type
. Use a similar type name forsubStruct_C
.
Each signal element inA_struct_type
uses another bus object as a data type. Now, these elements represent substructures.
5. Use the Bus Editor to create theSimulink.Bus
objectsB_struct_type
(with three signal elements) andC_struct_type
(with two signal elements).
6. In the dialog box of the Bus Creator block that collects the three Gain signals, setOutput data typetoBus: B_struct_type
. ClickApply.
7. SelectOutput as nonvirtual busand clickOK.
8. In the dialog box of the other subordinate Bus Creator block, setOutput data typetoBus: C_struct_type
and selectOutput as nonvirtual bus. ClickOK.
9. In the last Bus Creator block dialog box, setOutput data typetoBus: A_struct_type
and selectOutput as nonvirtual bus. ClickOK.
10. On theModelingtab, clickModel Data Editor.
11. In the Model Data Editor, on theSignalstab, from theChange viewdrop-down list, selectCode
.
12. In the model, click the output signal of theA_struct_type
Bus Creator block, which feeds the Unit Delay block.
13. In the Model Data Editor, for the output of the Bus Creator block, setNametosig_struct_var
.
14. SetStorage ClasstoExportedGlobal
. With this setting, the output of the Bus Creator block appears in the generated code as a separate global structure variable namedsig_struct_var
.
15. Generate code from the model.
Results
The generated header fileex_signal_nested_struct_types.h
defines the structure types. Each structure type corresponds to aSimulink.Bus
object.
typedef struct { real_T signal1; real_T signal2; real_T signal3; } B_struct_type; typedef struct { real_T signal1; real_T signal2; } C_struct_type; typedef struct { B_struct_type subStruct_B; C_struct_type subStruct_C; } A_struct_type;
The generated source fileex_signal_nested_struct.c
allocates memory for the global structure variablesig_struct_var
. By default, the name of theA_struct_type
Bus Creator block isBus Creator2
.
/* Exported block signals */ A_struct_type sig_struct_var; /* '/Bus Creator2' */
In the same file, in the modelstep
function, the algorithm accessessig_struct_var
and the fields ofsig_struct_var
.
Combine Techniques to Work Around Limitations
To work around some of the limitations of each technique, you can combine structured storage classes with nonvirtual buses and parameter structures. For example, you can:
Include a structure of signal data and a structure of parameter data in the same parent structure.
Nest structures while aggregating new data by default.
In the generated code, a flat parent structure, which corresponds to the structured storage class, contains substructures, which correspond to each bus and parameter structure. Choose one of these combined techniques:
Apply the structured storage class directly to each bus and parameter structure. For example, set the storage class of two nonvirtual bus signals to
Struct
. Each bus appears in the generated code as a field (substructure) of a single structure.Leave the storage class of each bus and parameter structure at the default setting,
Auto
, or atModel default
, which prevents code generation optimizations from eliminating the bus or parameter structure. Then, configure default storage classes such that signal data and parameter data use the structured storage class by default.
Arrays of Structures
You can further package multiple consistent bus signals or parameter structures into an array. The array of buses or parameter structures appears in the generated code as an array of structures. To create arrays of buses, seeCombine Buses into an Array of Buses(Simulink). To create arrays of parameter structures, seeGroup Multiple Parameter Structures into an Array(Simulink).
Structure Padding
By default, the code generator does not explicitly add padding fields to structure types. Structure types can appear in the generated code through, for example, the standard data structures (seeStandard Data Structures in the Generated Code),Simulink.Bus
objects, and parameter structures that you use in a model.
However, when you use a code replacement library with Embedded Coder, you can specify data alignment (including structure padding) as part of the replacement library. For more information, seeProvide Data Alignment Specifications for Compilers(Embedded Coder).
Limitations
With built-in金宝app®Coder™和嵌入式编码的特性,不能生成or use a custom structure that contains a field whose value is a pointer. You can do so manually by creating an advanced storage class and writing accompanying TLC code (seeFinely Control Data Representation by Writing TLC Code for a Storage Class(Embedded Coder)).
You cannot use the built-in storage class
Struct
, or a structured storage class that you create with the Custom Storage Class Designer (you set the storage class propertyTypetoFlatStructure
), to set data defaults in the Code Mapping Editor.
See Also
Related Topics
- 如何生成的代码存储内部信号,状态,and Parameter Data
- Exchange Data Between External C/C++ Code and Simulink Model or Generated Code
- 环境配置模型数据和函数ns for Code Generation(Embedded Coder)
- Control Data and Function Placement in Memory by Inserting Pragmas(Embedded Coder)
- Flexible Storage Class for Different Model Hierarchy Contexts(Embedded Coder)
- Types of Composite Signals(Simulink)