Skip to Main Content Skip to Search
Product Documentation

Data Stores

About Data Stores

A data store contains data that is accessible at any point in a model hierarchy at or below the level in which the data store is defined. Data stores can allow subsystems and referenced models to share data without having to use I/O ports to pass the data from level to level. See Working with Data Stores for information about data stores in Simulink. This section provides additional information about data store code generation.

Storage Classes for Data Store Memory Blocks

You can control how Data Store Memory blocks in your model are stored and represented in the generated code by assigning storage classes and type qualifiers. You do this in almost exactly the same way you assign storage classes and type qualifiers for block states.

Data Store Memory blocks, like block states, have Auto storage class by default, and their memory is stored within the DWork vector. The symbolic name of the storage location is based on the data store name.

You can generate code from multiple Data Store Memory blocks that have the same data store name, subject to the following restriction: at most one of the identically named blocks can have a storage class other than Auto. An error is reported if this condition is not met.

For blocks with Auto storage class, the Simulink Coder product generates a unique symbolic name for each block to avoid name clashes. For Data Store Memory blocks with storage classes other than Auto, the generated code uses the data store name as the symbol.

In the following model, a Data Store Write block writes to memory declared by the Data Store Memory block myData:

To control the storage declaration for a Data Store Memory block, use the Code generation storage class and Code generation type qualifier fields of the Data Store Memory block dialog box. The next figure shows the Data Store Memory block dialog box for the preceding model.

Data Store Memory blocks are nonvirtual because code is generated for their initialization in .c and .cpp files and their declarations in header files. The following table shows how the code generated for the Data Store Memory block in the preceding model differs for different settings of Code generation storage class. The table gives the variable declarations and MdlOutputs code generated for the myData block.

Storage Class

Declaration

Code

Auto

In model.h

typedef struct 
D_Work_tag 
{
  real_T myData;
} 
D_Work;

In model.c or model.cpp

/* Block states (auto storage) */
D_Work model_DWork;
model_DWork.myData = 
  rtb_SineWave;

ExportedGlobal

In model.c or model.cpp

/* Exported block states */
real_T myData; 

In model.h

extern real_T myData;
myData = rtb_SineWave;

ImportedExtern

In model_private.h

extern real_T myData;
myData = rtb_SineWave;

ImportedExternPointer

In model_private.h

extern real_T *myData;
(*myData) = rtb_SineWave;

Control Code Generation for Data Store Memory Blocks

If you are not familiar with Simulink data objects and signal objects, you should read Signals before reading this section.

You can associate a Data Store Memory block with a signal object, and control code generation for the block through the signal object. To do this:

  1. Instantiate the desired signal object.

  2. Set the object's CoderInfo.StorageClass property to indicate the desired storage class.

  3. Open the block dialog box for the Data Store Memory block that you want to associate with the signal object.

  4. Enter the name of the signal object in the Data store name field.

  5. Select Data store name must resolve to Simulink signal object.

  6. Do not set the storage class field to a value other than Auto (the default).

  7. Click OK or Apply.

      Note   When a Data Store Memory block is associated with a signal object, the mapping between the Data store name and the signal object name must be one-to-one. If two or more identically named entities map to the same signal object, the name conflict is flagged as an error at code generation time. See Resolve Conflicts in Configuration of Signals Objects for more information.

Nonscalar Data Stores in Generated Code

Stateflow generates efficient code for accessing individual elements of nonscalar data stores. For example, the next figure shows a data store named A that has seven elements. The Stateflow chart assigns the fourth element of the data store from a value computed from the third element. The generated code is efficient and involves no unnecessary access of any of the other elements of A.

In contrast, modeling and code generation for data store element selection and assignment in Simulink is more explicit. The next figure shows the same algorithm modeled without using a Stateflow chart. The assignment block copies each element of the data store back to itself, in addition to updating the element.

Data Store Buffering in Generated Code

A Data Store Read block is a nonvirtual block that copies the value of the data store to its output buffer when it executes. Since the value is buffered, all downstream blocks connected to the output of the data store read utilize the same value, even if a Data Store Write block updates the data store in between execution of two of the downstream blocks.

The next figure shows a model that uses blocks whose priorities have been modified to achieve a particular order of execution:

The following execution order applies:

  1. The block Data Store Read buffers the current value of the data store A at its output.

  2. The block Abs1 uses the buffered output of Data Store Read.

  3. The block Data Store Write updates the data store.

  4. The block Abs uses the buffered output of Data Store Read.

Because the output of Data Store Read is a buffer, both Abs and Abs1 use the same value: the value of the data store at the time that Data Store Read executes.

The next figure shows another example:

In this example, the following execution order applies:

  1. The block Data Store Read buffers the current value of the data store A at its output.

  2. Atomic Subsystem executes.

  3. The Sum block adds the output of Atomic Subsystem to the output of Data Store Read.

Simulink assumes that Atomic Subsystem might update the data store, so Simulink buffers the data store. Atomic Subsystem executes after Data Store Read buffers its output, and the buffer provides a way for the Sum block to use the value of the data store as it was when Data Store Read executed.

In some cases, theSimulink Coder code generator determines that it can optimize away the output buffer for a Data Store Read block, and the generated code will refer to the data store directly, rather than a buffered value of it. The next figure shows an example:

In the generated code, the argument of the fabs() function is the data store A rather than a buffered value.

  


Related Products & Applications

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.

 © 1984-2012- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS