Main Content

Configure Data Stores for C Code Generation

Data stores enable subsystems and referenced models to share data without using I/O ports to pass the data from level to level (see Data Store Basics and Data Stores in Generated Code). Types of data stores include the types listed in this table.

Type of Data StoreDescription
Local data storeData store that is accessible from anywhere in a model hierarchy that is at or below the level at which you define the data store. You can define a local data store graphically in a model by including a Data Store Memory block or by creating a signal object (synthesized data store) in the model workspace.
Shared local data storeData Store Memory block with the block parameter Share across model instances set. These data stores are accessible only in the model where they are defined. The data store value is shared across instances of the model.
Global data storeData store that is defined by a signal object in the base workspace or in a data dictionary. Multiple models in an application can use these data stores.

When you open a model in the Embedded Coder app, local and shared local data stores appear in the Code Mappings editor, where you can configure the data stores for code generation. If a model uses global data stores, you can view them in the Code Mappings editor by clicking the Refresh link that appears to the right of the data store name. That link initiates an update diagram and adds global data stores that the model uses in the editor view.

Configure data stores to:

  • Make data accessible for interaction while the generated code executes.

  • Control where the code generator places data in memory.

  • Improve readability and traceability of generated code.

For code generation, examples show how to configure a data store for model ConfigurationInterface. You can configure code mappings by using the Code Mappings Editor – C or code mappings API (coder.mapping.api.CodeMapping).

Choose Customization Options for Data Stores

By default, local data stores in a model appear in generated code as fields of a global data structure named model_DW. Shared local data stores appear as a field of global data structure model_SharedDSM. Based on your code interface requirements, decide whether to customize code generation of data stores. If you do not configure customizations, the code generator determines whether to eliminate or change the representation of data stores in generated code for optimization purposes. If you configure customizations, decide:

  • Whether to set up a default configuration

    If a model includes a significant number (for example, more than 10) of data stores for a given category that must be accessible during program execution, it is more efficient to configure the data stores with a default setting, and then override that setting for special cases. If the model includes a few data stores for a given category that have unique source, naming, or placement requirements, consider configuring the data stores individually.

  • How to declare and handle model data stores in the generated code

    • As separate global variables

    • To read from data stores as global variables defined in external code

    • As calls to access functions. Requires Embedded Coder®

    For more information about these options, see Control Data and Function Interface in Generated Code.

Other considerations for model parameters include whether to:

For a list of interface requirements that are relevant to data stores with corresponding storage classes and storage class properties, see Choose Storage Class and Storage Class Properties for Data Stores.

For example model ConfigurationInterface, data store requirements are:

  • Represent local data stores as separate global variables defined and declared with the static type qualifier.

  • Represent shared local data stores as separate global variables defined and declared with the volatile type qualifier.

  • Apply prefix ds_ to names of variables that represent data stores.

For this example, you set the default representation for local data stores in the generated code as global variables that have the static type qualifier and shared local data stores as global variables that have the volatile type qualifier. Then, you configure the local data store in the model to use the default storage class and a unique code identifier that includes the required prefix ds_. The code identifier capability enables you to specify code generation identifiers without having to modify the model design.

Configure Default Code Generation Settings for Data Stores

Default code generation settings for data stores can reduce the effort of preparing a model for code generation, especially if a model has a significant number of data stores that you want to gain access to while the generated code executes. Choose configuration settings once, and the code generator applies those settings to data stores across the model. Simulink® stores the default configuration as part of the model.

Consider configuring default code generation settings for model data stores if your model uses multiple data stores for a given category that do not have unique requirements or use a shared Embedded Coder Dictionary.

This example shows how to use the Code Mappings Editor – C to configure default settings for data stores. Use the Code Mappings editor to set the default storage class for local and shared local data stores in model ConfigurationInterface to FileScope and Volatile, respectively. With those storage class settings, the code generator represents the data stores in the generated code as global variables that have the static and volatile type qualifiers.

  1. Open model ConfigurationInterface. Save a copy of the model to a writable location.

    Simulink model to use for learning how to configure model data stores for code generation.

  2. Open the Embedded Coder app.

  3. In the C Code tab, select Code Interface > Default Code Mappings.

  4. Configure default code mappings for local data stores. In the Code Mappings editor, on the Data Defaults tab, expand the Signals node. Select category Signals, states, and internal data. Set the storage class to FileScope.

    Code Mappings editor with Data Defaults tab selected, Signals tree node expanded, and storage class for Signals, states, and internal data set to FileScope.

  5. Configure default code mappings for shared local data stores. Select category Shared local data stores. Set the storage class to Volatile.

  6. Save the model.

Configure Code Generation for Individual Data Stores

You can configure individual data stores for code generation. For example, if a model has two data stores of the same category that have unique code generation requirements, configure the data stores individually. Or, if you configure default settings for a category of data stores, you can override those settings for specific data stores.

If your model meets at least one of these criteria, consider configuring code generation settings for data stores individually:

  • Uses multiple data stores of the same category that have unique source, naming, or placement requirements.

  • Uses a few data stores of the same category.

  • Has a default configuration for a category of data stores and you need to override the configuration for some specific states.

This example shows how to use the Code Mappings editor to apply your default storage class setting to the Data Store Memory block mode in model ConfigurationInterface. The example also shows how configure a code identifier for that data store.

  1. If you have not already done so, complete the steps in Configure Default Code Generation Settings for Data Stores.

  2. In the Code Mappings editor, click the Data Stores tab. Expand Local Data Stores. The storage class for data store mode is set to Auto, which means that the code generator might eliminate or change the representation of relevant code for optimization purposes. If optimizations are not possible, the code generator applies the model default configuration. For this example, the model default configuration specifies the storage class Volatile.

    • To avoid optimizations and force the code generator to use the default configuration, set the storage class to Model default.

    • To override the default configuration, specify the storage class that meets the code generation requirements for that data store.

  3. In the Code Mappings editor, select local data store mode. Set the storage class to Model default: Volatile.

  4. Configure the code identifier for the data store with a name that includes the prefix ds_. In the Code Mappings editor, select shared local data store mode. Click the Icon to configure additional code mapping properties icon and set the storage class property Identifier to ds_mode.

    Code Mappings editor with Data Stores tab selected, Shared Local Data Stores tree node expanded, and storage class for data store mode set to Model default: Volatile. Mapping Inspector shows Identifier property for data store mode set to ds_mode.

  5. Save the model.

  6. Generate and view the code. For example, in ConfigurationInterface.c, find the data definitions for the data store.

    static boolean_T ds_mode;
    

    Find where the state data is used in the step entry-point function.

    .
    .
    .
      ds_mode = ((input1 > ConfigurationInterface_UPPER) || (input1 <
                  ConfigurationInterface_LOWER));
    .
    .
    .
      if (ds_mode) {
        output = (real_T)mp_K1 * dout_Table1;
      } else {
        output = dstate_X;
      }
    .
    .
    .
    

Configure Code Generation Settings for Data Stores Programmatically

To automate configuration of data stores for code generation, use the programming interface for code mappings. For example, when creating custom block libraries or part of an application test environment, use the programming interface to automate data configuration.

This example shows how to use the programming interface to configure data stores for model ConfigurationInterface. Set the default representation of local and shared local data stores in the generated code as global variables that have the static and volatile type qualifier, respectively. Configure the Data Store Memory block mode to use the default storage class and a unique code identifier that includes the required prefix ds_.

  1. Open the example model.

    openExample("ConfigurationInterface")
    
  2. Create object cm by calling function coder.mapping.api.get. The object stores the data and function code generation configuration for model ConfigurationInterface.

    cm = coder.mapping.api.get("ConfigurationInterface");
    
  3. Configure default settings for local data stores by calling function setDataDefault. For the arguments, specify these values:

    • The object returned by coder.mapping.api.get

    • InternalData for the default category

    • Property name StorageClass with property value FileScope

    setDataDefault(cm,"InternalData","StorageClass","FileScope");
    
  4. Configure default settings for shared local data stores by calling function setDataDefault. Specify these values for arguments:

    • The object returned by coder.mapping.api.get.

    • SharedLocalDataStore for the default category.

    • Property name StorageClass with property value Volatile.

    setDataDefault(cm,"SharedLocalDataStore","StorageClass","Volatile");
    
  5. Verify your default configuration settings for local and shared local data stores. Issue a call to getDataDefault that specifies the object returned by coder.mapping.api.get, category InternalData, and the property StorageClass. In a second call to getDataDefault, replace the category with SharedLocalDataStore.

    getDataDefault(cm,"Internal","StorageClass")
    
    ans =
    
        'FileScope'
    
  6. Apply the default configuration for local data store mode.

    By default, Simulink sets the storage class for data stores to Auto. When the storage class is Auto, the code generator:

    • Determines whether to eliminate the data from the generated code for optimization purposes.

    • If retaining the data, determines how to efficiently represent the data in the generated code, taking into account default configuration settings.

    To control the configuration for an individual data store, call function setDataStore. Issue a call to setDataStore that specifies:

    • Object returned by coder.mapping.api.get

    • Data store name mode

    • Default storage class previously set for the data store by using property StorageClass and property value Model default.

    • Property Identifier and property value ds_mode

    setDataStore(cm,"mode","StorageClass","Model default","Identifier","ds_mode");
    
  7. Verify your configuration changes by calling function getDataStore. Specify the object returned by coder.mapping.api.get, the name of the data store, and property StorageClass or Identifier.

    getDataStore(cm,"mode","StorageClass")
    
    ans =
    
        'Model default'
    
    getDataStore(cm,"mode","Identifier")
    
    ans =
    
        'ds_mode'
    
  8. Save the model.

  9. Generate and view the code. For example, in ConfigurationInterface.c, find the data definition for the data store.

    static boolean_T ds_mode;
    

    Find where the data store is used in the step entry-point function.

    .
    .
    .
      ds_mode = ((input1 > ConfigurationInterface_UPPER) || (input1 <
                  ConfigurationInterface_LOWER));
    .
    .
    .
      if (ds_mode) {
        output = (real_T)mp_K1 * dout_Table1;
      } else {
        output = dstate_X;
      }
    .
    .
    .
    

Choose Storage Class and Storage Class Properties for Data Stores

Depending on your code generation requirements, choose from these storage classes to configure code generation for data stores. The list of storage classes is defined in the coder dictionary.

RequirementsStorage Class for Default MappingsStorage Class for Individual Mappings
Enable optimizations, potentially generating more efficient code. Auto
For data elements that cannot be optimized, represent data as a field of a standard data structure.Default 
Prevent optimizations from eliminating storage for a data element and use the default storage class for the data element category. Model Default
When using a shared coder dictionary, select the dictionary default for data elements that you do not want the code generator to optimize.Dictionary Default 
Generate a structure that stores Boolean, fixed-point, or integer data in named bitfields. Bitfield (Individual mapping only)
Generate a global variable definition and declaration that has the volatile type qualifier.Volatile (See Const, Volatile, and ConstVolatile)Volatile (See Const, Volatile, and ConstVolatile)
Generate a global variable definition and declaration.ExportedGlobalExportedGlobal
Generate a global variable definition and declaration to a specified file.ExportToFileExportToFile
Generate code that interacts with data by calling your custom accessor functions.GetSetGetSet
Generate a global variable definition and declaration that has the static type qualifier.FileScope (Local and shared local data store mappings only)FileScope (Local and shared local data store mappings only)
Generate code that interacts with data by calling your custom accessor functions.GetSetGetSet
Generate code that reads from and writes to a global variable or global variable pointer defined by your external code.ImportedExtern, ImportedExternPointerImportedExtern, ImportedExternPointer
Generate code that reads from and writes to a global variable defined by your external header file.ImportFromFileImportFromFile
Generate variables that are local to functions.LocalizableLocalizable
Generate a global structure that has a name, which you can specify. Struct
Generate a global variable that enables buffer reuse. Reusable
Generate variables for single-instance data and generate structures for multi-instance data.MultiInstance MultiInstance

The list of available storage classes might 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 have Embedded Coder software, you can define a storage class. See Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture.

For an individual data store, use the Identifier storage class property to configure a name for the variable representing the data store in the generated code. With Embedded Coder, depending on the storage class that you choose, you can also configure these properties.

PropertyDescriptionStorage Classes
DefinitionFileSource definition file that contains definitions for global data, which is read by the data store and external codeExportToFile and Volatile
GetFunctionData store appears in the generated code as a call to a specified get functionGetSet
HeaderFileSource header file that contains declarations for global data, which is read by the data store and external codeExportToFile, GetSet, ImportFromFile, and Volatile
Memory Section (default data store configuration only)Memory section that contains data read by the data storeDefault
OwnerCode generator places the definition for data stores in the code generated for one of multiple models in a model hierarchy that share definitions. You must select the model configuration parameter Use owner from data object for data definition placement. See Control Placement of Global Data Definitions and Declarations in Generated Files.ExportToFile and Volatile
PreserveDimensionsCode generator preserves dimensions of data stores that are represented in generated code as a multidimensional array. You must set the model configuration parameter Array layout to Row-major. See Preserve Dimensions of Multidimensional Arrays in Generated Code.ExportToFile, FileScope, GetSet, ImportFromFile, Localizable and Volatile
SetFunctionData store appears in the generated code as a call to a specified set function.GetSet
StructNameName for a structure in the generated code for the data store.BitField and Struct

See Also

|

Related Topics