Доступ к сигналу, состоянию и данным о параметре во время выполнения

Когда вы итеративно разрабатываете модель, вы получаете выходной сигнал и утверждаете данные, которые генерирует выполнение модели. Вы также значения настройки параметров во время выполнения, чтобы наблюдать результаты относительно выходных параметров. Можно затем основывать проектные решения на анализе этих выходных параметров. Чтобы получить доступ к этому сигналу, состоянию и данным о параметре в среде быстрого прототипирования, можно сконфигурировать сгенерированный код, чтобы хранить данные в адресуемой памяти.

По умолчанию настройки оптимизации делают сгенерированный код более эффективным путем устранения ненужного устройства хранения данных сигнала и встраивания числовых значений параметров блоков. Чтобы сгенерировать код, который вместо этого выделяет адресуемую память для этих данных, можно отключить оптимизацию или задать настройки генерации кода для отдельных элементов данных.

Исследуйте модель в качестве примера

Запустите скрипт, который готовит модель rtwdemo_configrpinterface к этому примеру.

prepare_rtwdemo_configrpinterface

Эти данные сконфигурированы для генерации кода:

  • Параметры UPPERниже, K1, Table1, и Table2

  • Сигналы In1, In2, In3, In4, и Out1

  • Состояния X (задержка) и mode (запись памяти хранилища данных)

Откройте модель в качестве примера, rtwdemo_configrpinterface.

rtwdemo_configrpinterface

Модель загружает числовые переменные MATLAB в рабочее пространство модели. Переменные рабочей области устанавливают некоторые параметры блоков в модели. Однако блок Gain в модели использует литеральное значение 2.

Отключите оптимизацию

1. В модели очистите Повторное использование памяти параметра конфигурации модели. Когда вы очищаете эту оптимизацию и другую оптимизацию ту, которая Устраняет лишние локальные переменные (сворачивание выражения), сгенерированный код выделяет память для сигнальных линий. Очистка Повторного использования памяти отключает большую часть другой оптимизации.

set_param('rtwdemo_configrpinterface','OptimizeBlockIOStorage','off')

2. Установите поведение параметра Значения по умолчанию параметра конфигурации модели на Tunable. Когда установлено в Tunable, этот параметр конфигурации заставляет сгенерированный код выделять память для переменных рабочей области и параметров блоков.

set_param('rtwdemo_configrpinterface','DefaultParameterBehavior','Tunable')

3. Сгенерируйте код.

slbuild('rtwdemo_configrpinterface')
### Starting build procedure for: rtwdemo_configrpinterface
### Successful completion of build procedure for: rtwdemo_configrpinterface

Build Summary

Top model targets built:

Model                      Action                       Rebuild Reason                                    
==========================================================================================================
rtwdemo_configrpinterface  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 25.007s

4. В отчете генерации кода просмотрите файл rtwdemo_configrpinterface.h. Этот заголовочный файл задает тип структуры, который содержит данные сигнала. Структура содержит поля, что каждый представляет сигнальную линию в модели. Например, выходной сигнал блока Gain, именем которого является Gain, появляется как поле Gain.

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.h');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_configrpinterface_T;',1,1)
/* Block signals (default storage) */
typedef struct {
  real_T Delay;                        /* '<Root>/Delay' */
  real_T Table2;                       /* '<Root>/Table2' */
  real_T Table1;                       /* '<Root>/Table1' */
  real_T Gain;                         /* '<Root>/Gain' */
  boolean_T RelOp1;                    /* '<Root>/RelOp1' */
  boolean_T RelOp2;                    /* '<Root>/RelOp2' */
  boolean_T LogOp;                     /* '<Root>/LogOp' */
  boolean_T DataStoreRead;             /* '<Root>/Data Store Read' */
} B_rtwdemo_configrpinterface_T;

Файл задает тип структуры, который содержит данные о параметрах блоков. Например, параметр Усиления блока Gain появляется как поле Gain_Gain. Другие поля структуры представляют другие параметры блоков и переменные рабочей области из модели, включая начальные условия для сигналов и состояний.

rtwdemodbtype(file,'/* Parameters (default storage) */',...
    '/* Real-time Model Data Structure */',1,0)
/* Parameters (default storage) */
struct P_rtwdemo_configrpinterface_T_ {
  Table1_Type Table1;                  /* Variable: Table1
                                        * Referenced by: '<Root>/Table1'
                                        */
  Table2_Type Table2;                  /* Variable: Table2
                                        * Referenced by: '<Root>/Table2'
                                        */
  real_T LOWER;                        /* Variable: LOWER
                                        * Referenced by: '<Root>/Constant2'
                                        */
  real_T UPPER;                        /* Variable: UPPER
                                        * Referenced by: '<Root>/Constant1'
                                        */
  real_T Gain_Gain;                    /* Expression: 2
                                        * Referenced by: '<Root>/Gain'
                                        */
  real_T Delay_InitialCondition;       /* Expression: 0
                                        * Referenced by: '<Root>/Delay'
                                        */
  uint32_T Table2_maxIndex[2];         /* Computed Parameter: Table2_maxIndex
                                        * Referenced by: '<Root>/Table2'
                                        */
  boolean_T DataStoreMemory_InitialValue;
                             /* Computed Parameter: DataStoreMemory_InitialValue
                              * Referenced by: '<Root>/Data Store Memory'
                              */
};

5. Просмотрите файл rtwdemo_configrpinterface_data.c. Этот исходный файл выделяет глобальную память для структуры параметра и инициализирует значения полей на основе значений параметров в модели.

6. Просмотрите исходный файл rtwdemo_configrpinterface.c. Код выделяет глобальную память для переменной структуры, которая содержит данные сигнала.

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.c');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_configrpinterface_T rtwdemo_configrpinterface_B;',1,1)
/* Block signals (default storage) */
B_rtwdemo_configrpinterface_T rtwdemo_configrpinterface_B;

Алгоритм кода в модели step функция вычисляет значения сигналов. Это затем присваивает эти значения полям структуры сигнала. Чтобы выполнить вычисления, алгоритм использует значения параметров от полей структуры параметра.

Исключите элементы данных из оптимизации

Когда это необходимо, чтобы выбрать оптимизацию генерации кода, такую как Повторное использование памяти, можно сохранить отдельные элементы данных от оптимизации. Сгенерированный код затем выделяет адресуемую память для элементов.

Выберите оптимизацию, которую вы ранее очистили.

set_param('rtwdemo_configrpinterface','OptimizeBlockIOStorage','on')
set_param('rtwdemo_configrpinterface','LocalBlockOutputs','on')
set_param('rtwdemo_configrpinterface','DefaultParameterBehavior','Inlined')

1. Во вкладке C Code выберите Code Interface> Individual Element Code Mappings.

2. В редакторе Отображений Кода смотрите вкладку Signals/States.

3. В модели выберите выходной сигнал блока Gain.

4. Сделайте паузу на замещающем знаке, который, кажется, выше или ниже сигнальной линии открывает строку меню. Нажмите Добавить Сигнальную кнопку. В редакторе Отображений Кода узел Сигналов расширяет и перечисляет сигнал, что вы добавили.

cm = coder.mapping.api.get('rtwdemo_configrpinterface');
gain_ports = get_param('rtwdemo_configrpinterface/Gain','PortHandles');
gain_outPort = gain_ports.Outport;
addSignal(cm,gain_outPort);

5. Примените класс памяти по умолчанию для Выходных портов к сигналу установкой Storage Class к Model default.

setSignal(cm,gain_outPort,'StorageClass','Model default','Identifier','Gain');

6. В модели выберите блок Gain.

7. В Property Inspector, установленном значение усиления к объекту параметра рабочего пространства модели K1.

8. В редакторе Отображений Кода, на вкладке Parameters, расширяют Параметры модели.

9. Выберите параметр K1. Примените класс памяти кроме Auto путем установки Класса памяти. Например, используйте класс памяти Model default. При помощи Model default, K1 получает класс памяти по умолчанию, заданный для параметров модели, Default, и появляется как поле глобальной структуры параметров.

set_param('rtwdemo_configrpinterface/Gain','Gain','K1');
setModelParameter(cm,'K1','StorageClass','Model default');

10. Сгенерируйте код.

slbuild('rtwdemo_configrpinterface')
### Starting build procedure for: rtwdemo_configrpinterface
### Successful completion of build procedure for: rtwdemo_configrpinterface

Build Summary

Top model targets built:

Model                      Action                       Rebuild Reason                   
=========================================================================================
rtwdemo_configrpinterface  Code generated and compiled  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 9.6965s

11. В отчете генерации кода просмотрите файл rtwdemo_configrpinterface.h. Структура, которая содержит данные сигнала теперь, задает только одно поле, Gain, который представляет выход с концом теста блока Gain.

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.h');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_configrpinterface_T;',1,1)
/* Block signals (default storage) */
typedef struct {
  real_T Gain;                         /* '<Root>/Gain' */
} B_rtwdemo_configrpinterface_T;

Структура, которая содержит данные о параметрах блоков, задает одно поле, K1, который представляет объект параметра K1.

rtwdemodbtype(file,'/* Parameters (default storage) */',...
    '/* Real-time Model Data Structure */',1,0)
/* Parameters (default storage) */
struct P_rtwdemo_configrpinterface_T_ {
  int8_T K1;                           /* Variable: K1
                                        * Referenced by: '<Root>/Gain'
                                        */
};

Доступ к данным через сгенерированные интерфейсы

Можно сконфигурировать сгенерированный код, чтобы содержать дополнительный код и файлы так, чтобы можно было получить доступ к данным модели через стандартизированные интерфейсы. Например, используйте API C, чтобы регистрировать данные сигнала и настройки параметров во время выполнения.

Скопируйте этот пользовательский исходный код в файл с именем ex_myHandCode.c в вашей текущей папке.

#include "ex_myHandHdr.h"
 
#define paramIdx 0 /* Index of the target parameter, 
determined by inspecting the array of structures generated by the C API. */
#define sigIdx 0 /* Index of the target signal, 
determined by inspecting the array of structures generated by the C API. */
 
void tuneFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr)
{
    /* Take action with the parameter value only at 
       the beginning of simulation and at the 5-second mark. */
    if (*tPtr == 0 || *tPtr == 5) {
        
        /* Local variables to store information extracted from 
           the model mapping information (mmi). */
        void** dataAddrMap;
        const rtwCAPI_DataTypeMap *dataTypeMap;
        const rtwCAPI_ModelParameters *params;
        int_T addrIdx;
        uint16_T dTypeIdx;
        uint8_T slDataType;
        
        /* Use built-in C API macros to extract information. */
        dataAddrMap = rtwCAPI_GetDataAddressMap(mmi);
        dataTypeMap = rtwCAPI_GetDataTypeMap(mmi);
        params = rtwCAPI_GetModelParameters(mmi);
        addrIdx = rtwCAPI_GetModelParameterAddrIdx(params,paramIdx);
        dTypeIdx =  rtwCAPI_GetModelParameterDataTypeIdx(params,paramIdx);
        slDataType = rtwCAPI_GetDataTypeSLId(dataTypeMap, dTypeIdx);
        
        /* Handle data types 'double' and 'int8'. */
        switch (slDataType) {
            
            case SS_DOUBLE: {
                real_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                /* At the 5-second mark, increment the parameter value by 1. */
                if (*tPtr == 5) {
                    (*dataAddress)++;
                }
                printf("Parameter value is %f\n", *dataAddress);
                break;
            }
            
            case SS_INT8: {
                int8_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                if (*tPtr == 5) {
                    (*dataAddress)++;
                }
                printf("Parameter value is %i\n", *dataAddress);
                break;
            }
        }
    }
}
 
void logFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr)
{
    /* Take action with the signal value only when 
       the simulation time is an integer value. */
    if (*tPtr-(int_T)*tPtr == 0) {
        
        /* Local variables to store information extracted from 
           the model mapping information (mmi). */
        void** dataAddrMap;
        const rtwCAPI_DataTypeMap *dataTypeMap;
        const rtwCAPI_Signals *sigs;
        int_T addrIdx;
        uint16_T dTypeIdx;
        uint8_T slDataType;
        
        /* Use built-in C API macros to extract information. */
        dataAddrMap = rtwCAPI_GetDataAddressMap(mmi);
        dataTypeMap = rtwCAPI_GetDataTypeMap(mmi);
        sigs = rtwCAPI_GetSignals(mmi);
        addrIdx = rtwCAPI_GetSignalAddrIdx(sigs,sigIdx);
        dTypeIdx =  rtwCAPI_GetSignalDataTypeIdx(sigs,sigIdx);
        slDataType = rtwCAPI_GetDataTypeSLId(dataTypeMap, dTypeIdx);
        
        /* Handle data types 'double' and 'single'. */
        switch (slDataType) {
            
            case SS_DOUBLE: {
                real_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                printf("Signal value is %f\n", *dataAddress);
                break;
            }
            
            case SS_SINGLE: {
                real32_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                printf("Signal value is %f\n", *dataAddress);
                break;
            }
        }
    }
}

2. Скопируйте этот пользовательский код заголовка в файл с именем ex_myHandHdr.h в вашей текущей папке.

#include <stdio.h>
#include <string.h>
#include <math.h>
/* Include rtw_modelmap.h for definitions of C API macros. */
#include "rtw_modelmap.h"
#include "builtin_typeid_types.h"
#include "rtwtypes.h"
void tuneFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr);
void logFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr);

Эти файлы используют API C, чтобы получить доступ к сигналу и данным о параметре в коде, который вы генерируете из модели в качестве примера.

3. Установите Заголовочный файл параметров конфигурации модели и Исходные файлы к #include "ex_myHandHdr.h" и ex_myHandCode.c, соответственно.

set_param('rtwdemo_configrpinterface','CustomHeaderCode','#include "ex_myHandHdr.h"')
set_param('rtwdemo_configrpinterface','CustomSource','ex_myHandCode.c')

4. Выберите Логгирование MAT-файла параметра конфигурации модели. Сгенерированный исполняемый файл запускается только до времени остановки симуляции (который вы устанавливаете в параметрах конфигурации модели).

set_param('rtwdemo_configrpinterface','MatFileLogging','on')

5. Выберите параметры параметров конфигурации модели C API, сигналы, состояния и ввод-вывод корневого уровня.

set_param('rtwdemo_configrpinterface','RTWCAPIParams','on')
set_param('rtwdemo_configrpinterface','RTWCAPISignals','on')
set_param('rtwdemo_configrpinterface','RTWCAPIStates','on')
set_param('rtwdemo_configrpinterface','RTWCAPIRootIO','on')

6. Загрузите библиотеку блоков Пользовательского кода.

custcode

7. Добавьте блок System Outputs в модель.

add_block('custcode/System Outputs','rtwdemo_configrpinterface/System Outputs')

8. В Системе Выходное диалоговое окно блока, Система набора Выходной Код Выполнения Функции к этому коду:

{
rtwdemo_configrpinterface_U.input2++;
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_configrpinterface_M).mmi);
tuneFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));
}

9. В диалоговом окне блока, Система набора Выходной Код выхода Функции к этому коду:

{
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_configrpinterface_M).mmi);
logFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));
}

В качестве альтернативы, чтобы сконфигурировать блок System Outputs, в командной строке, используют эти команды:

temp.TLCFile = 'custcode';
temp.Location = 'System Outputs Function';
temp.Middle = sprintf(['{\nrtwdemo_configrpinterface_U.input2++;'...
    '\nrtwCAPI_ModelMappingInfo *MMI = '...
    '&(rtmGetDataMapInfo(rtwdemo_configrpinterface_M).mmi);'...
    '\ntuneFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));\n}']);
temp.Bottom = sprintf(['{\nrtwCAPI_ModelMappingInfo *MMI = '...
    '&(rtmGetDataMapInfo(rtwdemo_configrpinterface_M).mmi);'...
    '\nlogFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));\n}']);
set_param('rtwdemo_configrpinterface/System Outputs','RTWdata',temp)

10. Сгенерируйте код.

slbuild('rtwdemo_configrpinterface')
### Starting build procedure for: rtwdemo_configrpinterface
### Successful completion of build procedure for: rtwdemo_configrpinterface

Build Summary

Top model targets built:

Model                      Action                       Rebuild Reason                   
=========================================================================================
rtwdemo_configrpinterface  Code generated and compiled  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 11.098s

11. В отчете генерации кода просмотрите интерфейсный файл rtwdemo_configrpinterface_capi.c. Этот файл инициализирует массивы структур, которые можно использовать, чтобы взаимодействовать с элементами данных через API C. Например, в массиве структур rtBlockSignals, первая структура (индекс 0) описывает выходной сигнал с концом теста блока Gain в модели.

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface_capi.c');
rtwdemodbtype(file,'/* Block output signal information */',...
    '/* Individual block tuning',1,0)
/* Block output signal information */
static const rtwCAPI_Signals rtBlockSignals[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 0, 0, TARGET_STRING("rtwdemo_configrpinterface/Gain"),
    TARGET_STRING(""), 0, 0, 0, 0, 0 },

  {
    0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
  }
};

Поля структуры, такие как addrMapIndex, укажите на индексы в другие массивы структур, такие как rtDataAddrMap, это описывает характеристики сигнала. Эти характеристики включают адрес данных сигнала (указатель на данные), тип числовых данных и размерности сигнала.

12. В файле rtwdemo_configrpinterface.c, просмотрите алгоритм кода в модели step функция. Алгоритм сначала выполняет код, который вы задали в блоке System Outputs.

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.c');
rtwdemodbtype(file,'/* user code (Output function Body) */',...
    '/* Logic: ''<Root>/LogOp'' incorporates:',1,0)
  /* user code (Output function Body) */

  /* System '<Root>' */
  {
    rtwdemo_configrpinterface_U.input2++;
    rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo
      (rtwdemo_configrpinterface_M).mmi);
    tuneFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));
  }

  /* DataStoreWrite: '<Root>/Data Store Write' incorporates:
   *  Constant: '<Root>/Constant1'
   *  Constant: '<Root>/Constant2'
   *  Inport: '<Root>/In1'
   *  Logic: '<Root>/LogOp'
   *  RelationalOperator: '<Root>/RelOp1'
   *  RelationalOperator: '<Root>/RelOp2'
   */
  mode = ((rtwdemo_configrpinterface_U.In1 > 10.0) ||
          (rtwdemo_configrpinterface_U.In1 < -10.0));

  /* Gain: '<Root>/Gain' incorporates:
   *  Inport: '<Root>/In2'
   *  Lookup_n-D: '<Root>/Table1'
   */
  rtwdemo_configrpinterface_B.Gain = (real_T)rtwdemo_configrpinterface_P.K1 *
    look1_binlc(rtwdemo_configrpinterface_U.input2, rtCP_Table1_bp01Data,
                rtCP_Table1_tableData, 10U);

  /* Switch: '<Root>/Switch' incorporates:
   *  DataStoreRead: '<Root>/Data Store Read'
   */
  if (mode) {
    /* Outport: '<Root>/Out1' */
    output = rtwdemo_configrpinterface_B.Gain;
  } else {
    /* Outport: '<Root>/Out1' incorporates:
     *  UnitDelay: '<Root>/Delay'
     */
    output = rtwdemo_configrpinterface_DW.X;
  }

  /* End of Switch: '<Root>/Switch' */

  /* Lookup_n-D: '<Root>/Table2' incorporates:
   *  Inport: '<Root>/In3'
   *  Inport: '<Root>/In4'
   */
  rtwdemo_configrpinterface_DW.X = look2_binlc(rtwdemo_configrpinterface_U.In3,
    rtwdemo_configrpinterface_U.In4, rtCP_Table2_bp01Data, rtCP_Table2_bp02Data,
    rtCP_Table2_tableData, rtCP_Table2_maxIndex, 3U);

  /* user code (Output function Trailer) */

  /* System '<Root>' */
  {
    rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo
      (rtwdemo_configrpinterface_M).mmi);
    logFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));
  }

  /* Matfile logging */
  rt_UpdateTXYLogVars(rtwdemo_configrpinterface_M->rtwLogInfo,
                      (&rtwdemo_configrpinterface_M->Timing.taskTime0));

  /* signal main to stop simulation */
  {                                    /* Sample time: [1.0s, 0.0s] */
    if ((rtmGetTFinal(rtwdemo_configrpinterface_M)!=-1) &&
        !((rtmGetTFinal(rtwdemo_configrpinterface_M)-
           rtwdemo_configrpinterface_M->Timing.taskTime0) >
          rtwdemo_configrpinterface_M->Timing.taskTime0 * (DBL_EPSILON))) {
      rtmSetErrorStatus(rtwdemo_configrpinterface_M, "Simulation finished");
    }
  }

  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The absolute time is the multiplication of "clockTick0"
   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
   * overflow during the application lifespan selected.
   * Timer of this task consists of two 32 bit unsigned integers.
   * The two integers represent the low bits Timing.clockTick0 and the high bits
   * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
   */
  if (!(++rtwdemo_configrpinterface_M->Timing.clockTick0)) {
    ++rtwdemo_configrpinterface_M->Timing.clockTickH0;
  }

  rtwdemo_configrpinterface_M->Timing.taskTime0 =
    rtwdemo_configrpinterface_M->Timing.clockTick0 *
    rtwdemo_configrpinterface_M->Timing.stepSize0 +
    rtwdemo_configrpinterface_M->Timing.clockTickH0 *
    rtwdemo_configrpinterface_M->Timing.stepSize0 * 4294967296.0;
}

/* Model initialize function */
void rtwdemo_configrpinterface_initialize(void)
{
  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* initialize real-time model */
  (void) memset((void *)rtwdemo_configrpinterface_M, 0,
                sizeof(RT_MODEL_rtwdemo_configrpinte_T));
  rtmSetTFinal(rtwdemo_configrpinterface_M, 10.0);
  rtwdemo_configrpinterface_M->Timing.stepSize0 = 1.0;

  /* Setup for data logging */
  {
    static RTWLogInfo rt_DataLoggingInfo;
    rt_DataLoggingInfo.loggingInterval = (NULL);
    rtwdemo_configrpinterface_M->rtwLogInfo = &rt_DataLoggingInfo;
  }

  /* Setup for data logging */
  {
    rtliSetLogXSignalInfo(rtwdemo_configrpinterface_M->rtwLogInfo, (NULL));
    rtliSetLogXSignalPtrs(rtwdemo_configrpinterface_M->rtwLogInfo, (NULL));
    rtliSetLogT(rtwdemo_configrpinterface_M->rtwLogInfo, "");
    rtliSetLogX(rtwdemo_configrpinterface_M->rtwLogInfo, "");
    rtliSetLogXFinal(rtwdemo_configrpinterface_M->rtwLogInfo, "");
    rtliSetLogVarNameModifier(rtwdemo_configrpinterface_M->rtwLogInfo, "rt_");
    rtliSetLogFormat(rtwdemo_configrpinterface_M->rtwLogInfo, 0);
    rtliSetLogMaxRows(rtwdemo_configrpinterface_M->rtwLogInfo, 1000);
    rtliSetLogDecimation(rtwdemo_configrpinterface_M->rtwLogInfo, 1);
    rtliSetLogY(rtwdemo_configrpinterface_M->rtwLogInfo, "");
    rtliSetLogYSignalInfo(rtwdemo_configrpinterface_M->rtwLogInfo, (NULL));
    rtliSetLogYSignalPtrs(rtwdemo_configrpinterface_M->rtwLogInfo, (NULL));
  }

  /* block I/O */
  (void) memset(((void *) &rtwdemo_configrpinterface_B), 0,
                sizeof(B_rtwdemo_configrpinterface_T));

  /* Storage classes */
  output = 0.0;

  /* states (dwork) */
  (void) memset((void *)&rtwdemo_configrpinterface_DW, 0,
                sizeof(DW_rtwdemo_configrpinterface_T));

  /* exported global states */
  mode = false;

  /* external inputs */
  (void)memset(&rtwdemo_configrpinterface_U, 0, sizeof
               (ExtU_rtwdemo_configrpinterfac_T));

  /* Initialize DataMapInfo substructure containing ModelMap for C API */
  rtwdemo_configrpinterface_InitializeDataMapInfo();

  /* Matfile logging */
  rt_StartDataLoggingWithStartTime(rtwdemo_configrpinterface_M->rtwLogInfo, 0.0,
    rtmGetTFinal(rtwdemo_configrpinterface_M),
    rtwdemo_configrpinterface_M->Timing.stepSize0, (&rtmGetErrorStatus
    (rtwdemo_configrpinterface_M)));

  /* Start for DataStoreMemory: '<Root>/Data Store Memory' */
  mode = false;

  /* InitializeConditions for Lookup_n-D: '<Root>/Table2' incorporates:
   *  UnitDelay: '<Root>/Delay'
   */
  rtwdemo_configrpinterface_DW.X = 0.0;
}

/* Model terminate function */
void rtwdemo_configrpinterface_terminate(void)
{
  /* (no terminate code required) */
}

Этот код сначала тревожит входной сигнал input2 путем постепенного увеличения значения сигнала каждый раз step функция выполняется. Код затем использует встроенный макро-rtmGetDataMapInfo извлекать модель, сопоставляющую информацию от структуры данных модели rtwdemo_configrpinterface_M. Указатель MMI точки к извлеченной информации об отображении, которая позволяет функциям tuneFcn и logFcn получить доступ к информации содержало в массивах структур что файл API C rtwdemo_configrpinterface_capi.c задает.

13. Просмотрите функциональный tuneFcn в файле ex_myHandCode.c. Эта функция использует API C (через модель, сопоставляющую информацию mmi) и указатель на время симуляции, чтобы распечатать значение параметра K1 в конкретные моменты времени во время выполнения кода. Когда время симуляции достигает 5 секунд, функция изменяет значение параметров в памяти. При помощи switch case блокируйтесь, функция может получить доступ к данным о параметре, является ли типом данных int8 или double.

14. Просмотрите алгоритм кода в модели step функционируйте снова. Около конца функции алгоритм выполняет код, который вы задали в блоке System Outputs. Этот код вызывает функциональный logFcn.

rtwdemodbtype(file,'/* user code (Output function Trailer) */',...
    '/* Matfile logging */',1,0)
  /* user code (Output function Trailer) */

  /* System '<Root>' */
  {
    rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo
      (rtwdemo_configrpinterface_M).mmi);
    logFcn(MMI, rtmGetTPtr(rtwdemo_configrpinterface_M));
  }

15. Просмотрите функциональный logFcn в файле ex_myHandCode.c. Функция использует API C, чтобы распечатать значение сигнала с концом теста. Функция может получить доступ к данным сигнала, является ли типом данных single или double.

16. В командной строке запустите сгенерированный исполняемый rtwdemo_configrpinterface.exe.

system('rtwdemo_configrpinterface')

Параметр и значения сигналов появляются в окне Command Window.

Для получения дополнительной информации об интерфейсах данных, включая API C, смотрите Калибровку и Измерение.

Смотрите также

| |

Похожие темы