Main Content

Access Data Through Functions by Using Storage Classes in Embedded Coder Dictionary

To replace the direct access to data in the generated code with your own or legacy functions that read and write data in a customized way, you can enable function access on your storage classes. You create these storage classes in the Embedded Coder® Dictionary. Root-level inports, root-level outports, and model parameters that use your storage class appear in the generated code as calls to specified functions. You provide the function declarations and definitions in separate header and source files pointed to by the storage class.

Access Legacy Data by Value

You can define and apply a storage class to root-level inports, root-level outports, and model parameters so they can be accessed by customizable get and set functions. Such customization can be useful, for example, to abstract layers of software, gain access to data from an external file or to control access to critical sections of code.

This example shows how to set up a storage class in the Embedded Coder Dictionary and map the storage class to root-level inports/outports and model parameters in the Code Mappings editor.

  1. Open example model rtwdemo_roll. In the MATLAB command window, run this command:

    addpath(fullfile(docroot,'toolbox','ecoder','examples'))
    Running the preceding command gives you these supporting files required for the example that define the get and set functions:

    Save these files to your local path.

  2. In the Apps gallery, under Code Generation, click Embedded Coder.

  3. To open the Embedded Coder Dictionary, on the C Code tab, click Code Interface > Embedded Coder Dictionary.

  4. The rtwdemo_roll model has two storage classes: SignalStruct and ParamStruct. They are already created by using the Add button. This example uses these storage classes. You can perform the following steps for a storage class that you create as well.

  5. For the SignalStruct storage class, in the Property Inspector pane, update these property values:

    • Data Access to Function

    • Header File to $R_Value.h

    Make sure that Access Mode is set to Value. Data Scope is set to Imported by default and cannot be changed.

    For the ParamStruct storage class, in the Property Inspector pane, update these property values:

    • Data Access to Function

    • Header File to $R_Value.h

    These properties are already set:

    • Access Mode to Value

    • Data Initialization to Static

    Storage classes used for parameters can have only Data Initialization set to Static.

  6. Open the Configuration Parameters dialog box. Select Code Generation > Custom Code > Additional build information > Source files and specify:

    rtwdemo_roll_Value.c

  7. In the Embedded Coder app, open the Code Mappings editor. On the Data Defaults tab, map these model element categories:

    • Inports to SignalStruct

    • Outports to SignalStruct

    • Model parameters to ParamStruct

  8. Build the model and generate code.

In the generated code, view the file rtwdemo_roll.c. The model step function uses the specified get and set functions to execute the algorithm. The generated code accesses the legacy data by calling the custom, handwritten get and set functions. For example, here is the code snippet for the HDG_Ref inport:

if (get_HDG_Mode()) {
    /* Outputs for Atomic SubSystem: '<Root>/HeadingMode' */
    rtb_Sum1 = (get_HDG_Ref() - get_Psi()) * 0.015F * get_TAS();

    /* End of Outputs for SubSystem: '<Root>/HeadingMode' */
  } else {
    /* Outputs for Atomic SubSystem: '<Root>/RollAngleReference' */
    if ((real32_T)fabs(get_Turn_Knob()) >= 3.0F) {
      rtb_Sum1 = get_Turn_Knob();
    }
You can generate code that calls your custom get and set functions if the functions that you write accept and return the expected values.

Access Legacy Data by Pointer

To access data using a pointer, follow all the preceding steps but make these changes:

  • In the Embedded Coder Dictionary, for storage classes SignalStruct and ParamStruct, specify:

    • Access Mode to Pointer

    • Header File to $R_Pointer.h

  • Select Configuration Parameters > Code Generation > Custom Code > Additional build information > Source files and replace rtwdemo_roll_Value.c with:

    rtwdemo_roll_Pointer.c

With the pointer access, a get function now returns a pointer whose value must be dereferenced with the * before use. For example, the generated code for the HDG_Ref inport now looks like this code:

if (*get_HDG_Mode()) {
    /* Outputs for Atomic SubSystem: '<Root>/HeadingMode' */
    rtb_Sum1 = (*get_HDG_Ref() - *get_Psi()) * 0.015F * *get_TAS();

    /* End of Outputs for SubSystem: '<Root>/HeadingMode' */
  } else {
    /* Outputs for Atomic SubSystem: '<Root>/RollAngleReference' */
    if ((real32_T)fabs(tmp_1) >= 3.0F) {
      rtb_Sum1 = tmp_1;
    }

Creating your own storage class in Embedded Coder Dictionary gives you the flexibility of customizing function names and return types. You can also use the storage class GetSet to access data through get and set functions. For more information, see Access Data Through Functions with Storage Class GetSet.

See Also

Related Topics