Main Content

Generate C Measurement Service Interface Code for Component Deployment

Since R2022b

This example shows how to generate component code that includes interface support for measuring signal, state, and datastore data. The generated interface code must align with target environment interface requirements.

The example shows how to:

  1. Represent a measurable signal, state, and datastore data in the top model.

  2. Configure the code generator to apply a code interface.

  3. Generate and inspect the interface code.

Represent Measurement Data in Top Model

Open example component model ComponentDeploymentFcn.

open_system('ComponentDeploymentFcn');

component-deployment-fcn-model.png

The integrator and accumulator functions operate on state variables that you want to measure.

Open the function-call subsystems Integrator and Accumulator.

component-deployment-fcn-integrator-fcn.pngcomponent-deployment-fcn-accumulator-fcn.png

The integrator function uses a state variable to represent the discrete time integrator. The accumulator function uses a state variable to represent the delay. The target environment expects the names of the corresponding variables in the generated code to be CD_measured.dti and CD_measured.delay.

Configure Measurement Code Interface

The example model is linked to the shared Embedded Coder Dictionary file ComponentDeploymentCoderDictionary.sldd, which defines a service code interface configuration. That configuration defines a measurement service interface named MeasurementService. That service is configured to apply storage class SignalStruct. That storage class is defined with these property settings:

  • Access is set to Direct.

  • Data Scope is set to Exported.

  • Header File is set to $N.h, where $N is the model name.

  • Definition File is set to $N.c, where $N is the model name.

  • Use different property settings for single-instance and multi-instance data is cleared.

  • Storage Type is set to Structured.

  • Type Name is set to naming rule CD_measured_T$M.

  • Instance Name is set to naming rule CD_measured.

  • Data Initialization is set to Dynamic.

  • Memory Section is set to None.

  • Preserve array dimensions is cleared.

  • No qualifiers are specified.

Configure the model such that the code generator applies the coder dictionary default interface for measured data elements.

  1. Open the Embedded Coder app.

  2. Select Code Interface > Component Interface.

  3. In the Code Mappings editor, click the Signals/States tab.

  4. Expand the States node and select the row for Discrete-Time Integrator.

  5. From the menu in the Measurement Service column of the selected row, select Dictionary default: MeasurementService.

  6. In the selected row, click the pencil icon.

  7. In the dialog box that appears, set the Identifier property to dti. Alternatively, you can set the property in the Property Inspector.

  8. Select the row for Unit Delay.

  9. Repeat steps six and seven to set the Identifier property for the state to delay.

  10. Save configuration changes by saving the model.

Generate and Inspect Interface Code

Generate code from the example model. The code generator creates the folder ComponentDeploymentFcn_ert_rtw in the current working folder and places source code files in that folder. The generated code is in two primary files: header file ComponentDeploymentFcn.h and source code file ComponentDeploymentFcn.c. Model data and entry-point functions are accessible to a caller by including the header file in the target environment software.

To inspect the generated code, use the code generation report or, in the Embedded Coder app, use the Code view.

Header File

The header file ComponentDeploymentFcn.h includes interface header file services.h, defines an instance of the real-time model data structure, and declares structures and callable entry-point functions for data and function interface elements represented in the model.

This code fragment shows code in the header file that is relevant to measureable data.

typedef struct {
  real_T delay[10];
  real_T dti[10];
} CD_measured_T;
.
.
.
extern void CD_accumulator(void);
extern void CD_integrator(void);
extern CD_measured_T CD_measured;

Source Code File

This code fragment in generated source code file ComponentDeploymentFcn.c shows code relevant to the parameter tuning service interface.

CD_measured_T CD_measured;
.
.
.
void CD_accumulator(void)
{
  const real_T *tmpIrvIRead;
  int32_T i;
  tmpIrvIRead = get_CD_accumulator_DataTransfer();
  for (i = 0; i < 10; i++) {
    CD_measured.delay[i] += tmpIrvIRead[i];
    (getref_CD_accumulator_OutBus_y())[i] = CD_tunable.k * CD_measured.delay[i];
  }
}

void CD_integrator(void)
{
  real_T tmp;
  real_T *tmp_0;
  int32_T i;
.
.
.
  tmp = 1.25 * (real_T)Integrator_ELAPS_T;
  for (i = 0; i < 10; i++) {
    if ((int32_T)rtDWork.DiscreteTimeIntegrator_SYSTEM_E == 0) }
      CD_measured.dti[i] += tmp * rtDWork.DiscreteTimeIntegrator_PREV_U[i];
    }

    rtDWork.DiscreteTimeIntegrator_PREV_U[i] = get_CD_integrator_InBus_u())[i];
  }

  rtDWork.DiscreteTimeIntegrator_SYSTEM_E = 0U;
  memcpy(&tmp_0[0], &CD_measured.dti[0], (uint32_T)(10U * sizeof(real_T)));

void CD_initialize(void)
{
  {
    real_T *tmp;
    int32_T i;
    tmp = set_ModelInitialize_DataTransfer();
    for (i = 0; i < 10; i++) {
      tmp[i] = 5.0;
    }

    memcpy(&CD_measured.delay[0], &(get_CD_initialize_InBus_NVM())[0], (uint32_T) 
            (10U * sizeof(real_T)));
    rtDWork.Integrator_RESET_ELAPS_T = true;
    rtDWork.DiscreteTimeIntegrator_SYSTEM_E = 1U;

  } 
}

void CD_terminate(void)
{
  memcpy(&(getref_CD_terminate_OutBus_NVM())[0], &CD_measured.delay[0], 
        (uint32_T)(10U * sizeof(real_T)));
}

The accumulator and integrator functions use the state variables CD_states.dti and CD_states.delay in the for loops. The integrator, initialize, and terminate functions, use the variables for the memory copy operations.

Related Examples

More About