Choose Storage Class for Controlling Data Representation in Generated Code
A storage class is a code generation setting that you apply to data, such as parameters, signals, and states. During code configuration, use a storage class to control the appearance and placement of a data element in the generated code and to prevent optimizations from eliminating storage for that data element.
For model data, you can apply a storage class directly to a model data element by using the Code Mappings editor or code mappings API. Using either the editor or the API, apply a default storage class for categories of data, and then override that setting, as needed, for individual data elements.
For external data, you apply a storage class to a data object by using the Model Explorer
or programmatically by using functions such as get_param
and
set_param
.
Once you have specified a storage class for an element or category of elements, you can set properties for that storage class, such as header files, definition files, and memory sections.
Storage Class Properties
The property settings for a storage class define how and where the code generator represents data in the generated code. The properties that the user of a storage class can configure vary depending on the storage class. For most individual elements, the user can configure an identifier for naming the data element in the code. To identify properties that the user can configure for predefined storage classes, see the following information on specific storage classes.
When you create a storage class by using the Custom Storage Class Designer, you can choose whether the user of the storage class can specify additional settings. See Allow Users of Storage Class to Specify Property Value (Embedded Coder).
Default Storage Class
By default, the storage class for an individual data element is Auto
.
By using this default value, you are choosing to have the code generator handle storage
class selection and application. In this case, the data element is subject to code
generation optimizations, which can eliminate the element from the code or change the
representation of the element. If optimizations do not eliminate the data element, the
element appears as a field of a standard data structure in the generated code.
When using the Code Mappings editor or the code mappings API, a data element configured
with storage class Auto
that is not eliminated by optimizations acquires
the default code generation settings for the corresponding data category. If you do not
specify a code configuration for a category of data elements, the storage class is
Default
. When a data element category is using this storage class, data
elements in that category appear as a field of a standard data structure in the generated
code.
Built-in and Predefined Storage Classes
To prevent optimizations from eliminating storage for a data element, you can choose a
storage class for the element based on your code generation requirements. Available storage
classes include built-in storage classes, predefined storage classes in the
Simulink
package, and might also include other project-specific storage
classes defined in an Embedded Coder Dictionary. If you have special requirements that are
not met by the listed storage classes and you are generating code for an ERT-based target,
you can define and use a new storage class. See Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture (Embedded Coder) and Create Storage Classes by Using the Custom Storage Class Designer (Embedded Coder).
For Simulink® Coder™, you can choose from these built-in and predefined storage classes.
Requirements | Storage Class |
---|---|
Enable optimizations, potentially generating more efficient code. | Auto (Individual data elements) |
For data elements that cannot be optimized away, represent data as a field of a standard data structure. | Default (Default mapping) |
Prevent optimizations from eliminating storage for a data element. | Model Default (Individual mapping) |
Access data from a standalone global variable. Generated code contains the variable declaration and definition. | ExportedGlobal |
Access data from a standalone global variable. Generated code contains the variable declaration. Your external code provides the definition. | ImportedExtern, ImportedExternPointer |
If you have Embedded Coder®, you can choose from these additional predefined storage classes available in
the Simulink
package.
Requirements | Storage Class |
---|---|
Prevent optimizations from eliminating storage for a data element. | Dictionary Default (Default mapping) |
Generate standalone variables. | |
Generate variables as fields of a structure. | |
Generate variables that have a value that is fixed during code compilation. | |
Generate variables that you access through a function call. | GetSet |
Generate variables for single-instance data and generate structures for multi-instance data. | MultiInstance (Embedded Coder) |
These storage classes are examples of storage classes that you can add to an Embedded Coder Dictionary. These examples are defined and made available when you prepare a model for code generation by using the Quick Start tool.
Requirements | Storage Class |
---|---|
Generate global structures that contain parameter data and signal or state data. | ParamStruct, SignalStruct |
Note
Signal objects defined in the base workspace or a data dictionary with a non-auto storage class are not supported for models that are configured with an ERT-based system target file and service code interface.
Auto
When you select this storage class, the code generator handles how to represent the data in the generated code and can enable optimizations to operate on the data element, potentially generating more efficient code.
Auto
is the default storage class setting for each data element in a
model. The data element is subject to code generation optimizations, which can eliminate the
element from the code or change the representation of the element. For information about
these optimizations, such as those on the Configuration Parameters > Code Generation > Optimization pane, see How Generated Code Stores Internal Signal, State, and Parameter Data.
Optimizations cannot eliminate some data, such as most block states, from the code. The remaining data acquires a default storage class that you specify on the Data Defaults tab of the Code Mappings editor (see Configure Default Code Generation for Data (Embedded Coder)). If a data element cannot be eliminated, the name of the element in the code is based on naming rules that you specify by using model configuration parameters. See Identifier Format Control (Embedded Coder)—requires Embedded Coder.
Default
On the Data Defaults tab of the Code Mappings editor,
Default
is the default storage class setting for each data element
category. If you leave the storage class setting for a category at this value, data elements
that are not subject to code generation optimizations appear as a field of a standard data
structure. See How Generated Code Stores Internal Signal, State, and Parameter Data.
Model Default
When you configure an individual data element for code generation, use the
Model Default
storage class to prevent optimizations from eliminating
storage for a data element. See How Generated Code Stores Internal Signal, State, and Parameter Data. With this storage class
setting, the data element acquires the default storage class that you specify for the
corresponding data category on the Data Defaults tab of the Code
Mappings editor. The name of the data element in the code is the same as the name in the
model.
Dictionary Default
In Embedded Coder, if you link a model to a data dictionary, which includes a coder dictionary
that configures default code definitions for categories of data, you can use the Code
Mappings editor to apply the dictionary defaults. On the Data Defaults
tab, select a category, then set the storage class to Dictionary Default
.
For more information on configuring a default code mapping in a coder dictionary, see Configure Default Code Mapping in a Shared Dictionary (Embedded Coder).
ExportedGlobal
Use this built-in storage class to generate a global variable definition and
declaration. By default, the name of the variable is the name of the data element. The code
declares the variable in the generated file
, which you can include
(model
.h#include
) in your external code. The code generator does not optimize
this global variable from the generated code.
When you use this storage class, you can also configure this property.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
For an example that uses this storage class, see C Data Code Interface Configuration for Model Interface Elements.
ImportedExtern, ImportedExternPointer
To make a data element in a model represent a global variable that your external code
defines, use the built-in storage class ImportedExtern
. The generated
algorithmic code uses the variable without defining it.
Generate code that reads from and writes to a global variable defined by your external
code. The generated code declares the variable in the generated file
model
_private.h
so that the model
entry-point functions can read and write to the variable.
For example, you can apply the storage class ImportedExtern
to a
signal line, block state, or parameter object. For imported data:
The generated code does not initialize parameter data. Your code must initialize imported parameter data.
The generated initialization functions dynamically initialize some signal and state data. Unlike data that the generated code allocates, the code does not initialize imported signal or state data to a stored value of zero. Instead, the code immediately initializes the data to the real-world nonzero value that you specify in Simulink.
Note
The code generator initializes zero values that you specify in an Initialize Function block, even if those values have imported scope.
When your external code defines a data element and provides a pointer for accessing that
data, use ImportedExternPointer
. The generated code reads from and writes
to that pointer. The generated code declares the variable in the generated file
and reads and writes to
the data by dereferencing the pointer.model
_private.h
When you use these storage classes, you can also configure this property.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
Bitfield
Use this storage class to generate a structure that stores Boolean, fixed-point, or integer data in named bit fields.
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
StructName | Name of the structure for the data element in the generated code. |
For an example that uses this storage class, see Bitfields (Embedded Coder).
CompilerFlag
Use this storage class to support preprocessor conditionals defined by using a compiler flag or option.
If you build the generated code by using Embedded Coder, to specify the compiler option, you can use the model configuration parameter Configuration Parameters > Code Generation > Custom Code > Code information > Defines. See Code Generation Pane: Custom Code: Additional Build Information: Defines.
When you use this storage class, you can also configure this property.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
For an example that uses this storage class, see Compile Code Conditionally for Variations of Component Represented Using Variant Block.
Const, Volatile, and ConstVolatile
Use these storage classes to generate a global variable definition and declaration with
the const
, volatile
, or const
and
volatile
type qualifiers.
When you use these storage classes, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
HeaderFile | Source header file that contains declarations for global data read by the data element and external code. |
DefinitionFile | Source definition file that contains definitions for global data read by the data element and external code. |
Owner | Owner of global data that is defined with the code generated for one of multiple components that use that data. |
PreserveDimensions | When model configuration parameter Array
layout is set to |
For an example that uses this storage class, see Type Qualifiers (Embedded Coder).
Define, ImportedDefine
Use the Define
storage class to generate a macro
(#define
directive) such as #define myParam
5
.
Use ImportedDefine
to generate code that uses a macro
(#define
directive) defined in a header file in your external code. For
an example, see Macro Definitions (#define) (Embedded Coder).
When you use these storage classes, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
HeaderFile | Source header file that contains declarations for global data that is read by the data element and external code. |
Data elements that use this storage class do not appear in the code descriptor API or generated ARXML descriptions. For information about the code descriptor API, see Get Code Description of Generated Code. For information about generating ARXML descriptions, see Generate AUTOSAR C Code and XML Descriptions (AUTOSAR Blockset).
ExportToFile
Generate a global variable definition and declaration to an external file. You can specify the name and placement of the files that define and declare the variable. See Control Placement of Global Data Definitions and Declarations in Generated Files (Embedded Coder).
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
HeaderFile | Source header file where the code generator places the declarations for global data read by the data element and external code. |
DefinitionFile | Source definition file where the code generator places the definitions for global data read by the data element and external code. The code generator honors this setting only for single-instance models. The setting is ignored for reusable multi-instance models because the data definition is handled at the parent level. |
Owner | A component in the model hierarchy where the code generator places a global data definition instead of placing it in the top component of the hierarchy. Requires that you set the model configuration parameter Use owner from data object for data definition placement. |
PreserveDimensions | When model configuration parameter Array
layout is set to |
For an example that uses this storage class, see Definition, Initialization, and Declaration of Parameter Data (Embedded Coder).
FileScope
Use this storage class to generate a global variable definition and declaration that has
the static
type qualifier. In the generated code, the scope of the
variable is limited to the current file, which is typically
.model
.c
In a model reference hierarchy, if a referenced model uses a parameter object (such as
Simulink.Parameter
) that you create in the base workspace or a data
dictionary, you cannot apply FileScope
to the object. As a workaround,
move the parameter object into the model workspace of the referenced model. Then, you can
use FileScope
.
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
PreserveDimensions | When model configuration parameter Array
layout is set to |
GetSet
Use this storage class to generate code that interacts with data by calling custom accessor functions. Your external code defines the data and provides the function definitions.
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
HeaderFile | Source header file that contains declarations for the
|
GetFunction | Data element that appears in the generated code as a call to a specified
get function. |
SetFunction | Data element that appears in the generated code as a call to a specified
set function. |
PreserveDimensions | When model configuration parameter Array
layout is set to |
For an example that uses this storage class, see Access Data Through Functions with Storage Class GetSet (Embedded Coder).
ImportFromFile
Use this storage class to generate code that reads from and writes to a global variable
defined by your external code. ImportFromFile
is similar to
ExportToFile
, but the generated code does not define the
variable.
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
HeaderFile | Source header file that contains declarations for global data that is read by the data element and external code. To avoid linker errors, you must add include guards to the beginning of the header file. |
PreserveDimensions | When model configuration parameter Array
layout is set to |
For an example that uses this storage class, see Integrate External Application Code with Code Generated from PID Controller (Embedded Coder).
Localizable
For signals, if possible, minimize the use of global storage by using local variables.
If the variable is used in a single function, the variable is local to that function.
If the variable is used in a single file, the variable is local to that file.
If the variable is used in more than one function or file, the variable is a global.
Generating local variables prevents the code generator from removing the variables from the generated code.
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
PreserveDimensions | When model configuration parameter Array
layout is set to |
For an example that uses this storage class, see Generate Local Variables with Localizable Storage Class (Embedded Coder).
Reusable
Use this storage class to reuse the same variable for multiple independent signals in a model. The code generator stores intermediate calculations of a data path (a series of connected blocks) in a single, reused global variable.
When you use this storage class, you can also configure this property.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
For an example that uses this storage class, see Specify Buffer Reuse for Signals in a Path (Embedded Coder).
Struct
Use this storage class to generate a global structure with a name that you can specify.
When you use this storage class, you can also configure these properties.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
StructName | Name of the structure for the data element in the generated code. |
For an example that uses this storage class, see Organize Parameter Data into a Structure by Using Struct Storage Class (Embedded Coder) and Structures of Signals (Embedded Coder).
MultiInstance
To generate unstructured variables for single-instance data and structures for multi-instance data, use this storage class. When you apply this storage class to a data item, the Embedded Coder Dictionary determines if it is a single-instance storage class or a multi-instance storage class. The dictionary determines the type of class by the type of data and by the context of the model within the model reference hierarchy. You can duplicate this storage class to create a copy that you can edit.
When you apply this storage class to an individual data element, you can also configure the Identifier property. The Identifier property is an identifier string that the code generator uses to name the data element in the generated code.
For an example that uses this storage class, see Flexible Storage Class for Different Model Hierarchy Contexts (Embedded Coder).
ParamStruct, SignalStruct
Use these storage classes to generate global structures that contain parameter and signal or state data, respectively. In a hierarchy of components (referenced models or atomic subsystems), you can use these storage classes to create a corresponding hierarchy of structures. These storage classes appear in the Code Mappings editor only after preparing a model for code generation by using the Quick Start tool.
These storage classes are available only for model-owned data.
When you use these storage classes, you can also configure this property.
Property | Description |
---|---|
Identifier | Identifier string that the code generator uses to name the data element in the generated code. |
Storage Class Limitations
When you use storage classes in the Code Mappings editor (Embedded Coder) or code mappings API, some limitations apply. See Limitations (Embedded Coder).
Data objects cannot use an Embedded Coder storage class and a multiword data type.
For Embedded Coder storage classes in models that use referenced models:
If you apply a grouped storage class, such as
Struct
orBitfield
, to multiple data items, you must set the storage class Data scope property toImported
and you must provide the data declaration in an external header file. Grouped storage classes use a single variable in the generated code to represent multiple data objects.If a parameter object exists in the base workspace or a data dictionary, and a referenced model uses the object, you cannot apply the storage class
FileScope
. To apply this storage class to the parameter object, move the object into the model workspace of the referenced model.
You cannot apply the storage class
FileScope
to data items used by a data exchange interface (C API, external mode, or ASAP2) or MAT-file logging. File-scoped data is not externally accessible.You cannot apply the storage class
FileScope
to data that is used in multiple files.You cannot apply the storage class
Reusable
to signals that feed into Simulink Function block.
Related Topics
- C Data Code Interface Configuration for Model Interface Elements
- Organize Parameter Data into a Structure by Using Struct Storage Class (Embedded Coder)
- Configure Default C Code Generation for Categories of Data Elements and Functions (Embedded Coder)
- Control Data and Function Interface in Generated Code
- How Generated Code Stores Internal Signal, State, and Parameter Data