Documentation

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.

  • When you generate nonreetrant, single-instance code by setting the model configuration parameterCode interface packagingtoNonreusable function, create flat, global structure variables by applying the built-in storage classStruct. Alternatively, use example storage classes created by Quick Start tool,ParamStructandSignalStruct, or create and apply your own structured storage class.

  • When you generate multi-instance (reentrant) code from a model or a component, for example by settingCode interface packagingto a value other thanNonreusable function, in the Code Mappings editor, you cannot use the built-in storage classStructor a structured storage class that you create in a package. Instead, create your own structured storage class by using an Embedded Coder Dictionary. If you use the Embedded Coder Quick Start tool to prepare the model for code generation (seeGenerate Code by Using the Quick Start Tool(Embedded Coder)), you can use example storage classesParamStructandSignalStruct.

  • You cannot use this technique to aggregate global data stores or global parameters (which include parameter objects that you store in the base workspace or a data dictionary). For these kinds of data, use other techniques to create structures.

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 aSimulink.Busobject that represents the structure type that you want. Use the bus object to set the data types of nonvirtual bus signals and parameter structures in your model.

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 aSimulink.Busobject that represents the structure type that you want. If your external code already defines the type, use theSimulink.importExternalCTypesfunction to generate the bus object. Use the bus object to set the data types of nonvirtual bus signals and parameter structures in your model. For an example, seeExchange Structured and Enumerated Data Between Generated and External Code(Embedded Coder).

Reduce the number of arguments (formal parameters) for generated functions.

  • To reduce the number of arguments for the entry-point functions of the model from which you generate code, such asmodel_step, seeReduce Number of Arguments by Using Structures.

  • To reduce the number of arguments for the entry-point functions of a referenced model, in the referenced model:

  • To reduce the number of arguments for the entry-point functions of a masked, reentrant subsystem, aggregate mask parameters into a custom structure.

Organize lookup table data into a structure.

UseSimulink.LookupTableandSimulink.Breakpointobjects. 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 classStruct, 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 asExportedGlobalto 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 classesParamStructandSignalStructcreated 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 viewtoCodeand 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 aSimulink.Busobject 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 aSimulink.Busobject 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 theG2block 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.Parameterobject namedmyStructappears 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 fieldG2whose value is-2, and then close the Variable Editor.

10. In the Simulink.Parameter property dialog box, setStorage classtoExportedGlobal. The structuremyStructappears in the generated code as a global variable.

11. Generate code from the model.

Results

The generated header filertwdemo_paraminline_types.hdefines a structure type that has a random name.

typedef struct { real_T G1; real_T G2; } struct_6h72eH5WFuEIyQr5YrdGuB;

The source filertwdemo_paraminline.cdefines 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.createObjectto create aSimulink.Busobject 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 ofmyStructtoBus: 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.Busobject. Use the object as the data type of bus signals in your model.

2. Create theex_signal_structmodel 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.Busobject namedmy_signals_typethat 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.hdefines the structure typemy_signals_type.

typedef struct { real_T signal1; real_T signal2; real_T signal3; } my_signals_type;

The source fileex_signal_struct.callocates 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 modelstepfunction, the algorithm accessessig_struct_varand 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.Busobject. 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_structmodel 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.Busobject namedA_struct_typethat contains two signal elements:subStruct_BandsubStruct_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_Belement, setDataTypetoBus: B_struct_type. Use a similar type name forsubStruct_C.

Each signal element inA_struct_typeuses another bus object as a data type. Now, these elements represent substructures.

5. Use the Bus Editor to create theSimulink.BusobjectsB_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_typeand selectOutput as nonvirtual bus. ClickOK.

9. In the last Bus Creator block dialog box, setOutput data typetoBus: A_struct_typeand 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_typeBus 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.hdefines the structure types. Each structure type corresponds to aSimulink.Busobject.

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.callocates memory for the global structure variablesig_struct_var. By default, the name of theA_struct_typeBus Creator block isBus Creator2.

/* Exported block signals */ A_struct_type sig_struct_var; /* '/Bus Creator2' */

In the same file, in the modelstepfunction, the algorithm accessessig_struct_varand 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 toStruct. 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.Busobjects, 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

  • You cannot use the built-in storage classStruct, 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