MATLAB Examples

Use GetSet with Structured Data

This example shows how to apply the custom storage class GetSet to nonvirtual bus signals and structure parameters in a model.

View the example legacy header file ComponentDataHdr.h. The file defines a large structure type ComponentData.

rtwdemodbtype('ComponentDataHdr.h','/* ComponentData */','} ComponentData;',1,1)
/* ComponentData */

typedef struct {
    ScalarData scalars;
    VectorData vectors;
    StructData structs;
    MatricesData matrices;
} ComponentData;

The field structs is a substructure that uses the structure type StructData. The structure type StructData defines three fields: inStruct, structParam, and outStruct.

rtwdemodbtype('ComponentDataHdr.h','/* StructData */','} StructData;',1,1)
/* StructData */
        
typedef struct {
    SigBus inStruct;
    ParamBus structParam;
    SigBus outStruct;
} StructData;

The fields inStruct, structParam, and outStruct are also substructures that use the structure types SigBus and ParamBus. Each of these two structure types define three scalar fields.

rtwdemodbtype('ComponentDataHdr.h','/* SigBus */','} ParamBus',1,1)
/* SigBus */

typedef struct {
    double cmd;
    double sensor1;
    double sensor2;
} SigBus;

/* ParamBus */

typedef struct {
    double offset;
    double gain1;
    double gain2;
} ParamBus;

View the example legacy source file getsetSrc.c. The file defines and initializes a global variable ex_getset_data that uses the structure type ComponentData. The initialization includes values for the substructure structs.

rtwdemodbtype('getsetSrc.c','/* Field "structs" */','/* End of "structs" */',1,1)
    /* Field "structs" */
    { 
        {1.3, 5.7, 9.2},
                
        {12.3, 9.6, 1.76},
                
        {0.0, 0.0, 0.0}
    },
    /* End of "structs" */

The file also defines functions that read from and write to the fields of the substructure structs. The functions simplify data access by dereferencing the fields of the global structure variable ex_getset_data. The functions access the data in the fields inStruct, structParam, and outStruct by accepting and returning complete structures of the types SigBus and ParamBus.

rtwdemodbtype('getsetSrc.c',...
    '/* Structure get() and set() functions */','/* End of structure functions */',1,1)
/* Structure get() and set() functions */

SigBus get_inStruct(void)
{
    return ex_getset_data.structs.inStruct;
}

void set_inStruct(SigBus value)
{
    ex_getset_data.structs.inStruct = value;
}

ParamBus get_structParam(void)
{
    return ex_getset_data.structs.structParam;
}

void set_structParam(ParamBus value)
{
    ex_getset_data.structs.structParam = value;
}

SigBus get_outStruct(void)
{
    return ex_getset_data.structs.outStruct;
}

void set_outStruct(SigBus value)
{
    ex_getset_data.structs.outStruct = value;
}

View the example legacy header file getsetHdrStruct.h. The file contains the extern prototypes for the get and set functions defined in getsetSrc.c.

Open the example model rtwdemo_getset_struct. The model creates the data objects inStruct, structParam, and outStruct in the base workspace. The objects correspond to the signals and parameter in the model.

open_system('rtwdemo_getset_struct')

In the base workspace, double-click the object inStruct to view its properties. The object uses the custom storage class GetSet. The property HeaderFile is specified as getsetHdrStruct.h. This legacy header file contains the get and set function prototypes.

The model also creates the bus objects ParamBus and SigBus in the base workspace. The signals and parameter in the model use the bus types that these objects define. The property DataScope of each bus object is set to Imported. The property HeaderFile is set to ComponentDataHdr.h. The generated code imports these structure types from the legacy header file ComponentDataHdr.h.

In the model Configuration Parameters dialog box, on the Code Generation > Custom Code pane, the example legacy source file getsetSrc.c is identified for inclusion during the build process. This legacy source file contains the get and set function definitions and the definition of the global structure variable ex_getset_data.

Generate code with the example model.

rtwbuild('rtwdemo_getset_struct');
### Starting build procedure for model: rtwdemo_getset_struct
### Successful completion of build procedure for model: rtwdemo_getset_struct

In the code generation report, view the file rtwdemo_getset_struct.c. The model step function uses the legacy get and set functions to execute the algorithm.

rtwdemodbtype(fullfile('rtwdemo_getset_struct_ert_rtw','rtwdemo_getset_struct.c'),...
    '/* Model step function */','}',1,1)
/* Model step function */
void rtwdemo_getset_struct_step(void)
{
  /* Bias: '<Root>/Bias' incorporates:
   *  Inport: '<Root>/In1'
   */
  rtDW.BusCreator.cmd = get_inStruct().cmd + get_structParam().offset;

  /* Gain: '<Root>/Gain' incorporates:
   *  Inport: '<Root>/In1'
   */
  rtDW.BusCreator.sensor1 = get_structParam().gain1 * get_inStruct().sensor1;

  /* Gain: '<Root>/Gain1' incorporates:
   *  Inport: '<Root>/In1'
   */
  rtDW.BusCreator.sensor2 = get_structParam().gain2 * get_inStruct().sensor2;

  /* SignalConversion: '<Root>/Signal Conversion' */
  set_outStruct(rtDW.BusCreator);
}

When you use the custom storage class GetSet with structured data, the get and set functions that you provide must return and accept complete structures. The generated code dereferences individual fields of the structure that the get function returns.

The output signal of the Bus Creator block is a test point. This signal is the input for a Signal Conversion block. The test point and the Signal Conversion block exist so that the generated code defines a variable for the output of the Bus Creator block. To provide a complete structure argument for the function set_outStruct, you must configure the model to create this variable.