Сохраните переменные в сгенерированном коде

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

В зависимости от используемого системного целевого файла (например grt.tlc), по умолчанию настройки оптимизации могут сделать сгенерированный код более эффективным путем:

  • Устранение ненужного глобального и локального хранилища для сигналов и некоторых состояний.

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

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

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

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

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

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

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

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

prepare_rtwdemo_configrpinterface

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

  • Параметры UPPER, LOWER, 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 21.964s

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_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. В редакторе Code Mappings смотрите вкладку Signals/States.

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

4. Пауза на многоточии, которая появляется выше или ниже сигнальной линии, чтобы открыть панель действий. Нажмите кнопку Add Signal (добавить сигнал). В редакторе Code Mappings узел Signals расширяется и выводит добавленный сигнал.

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. Примените класс памяти по умолчанию для Outports к сигналу путем установки класса памяти на 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 7.5475s

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);

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

3. Установите параметры конфигурации модели Header file и Source files на #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. В диалоговое окно блока System Выходов установите System Выходов Function Выполнения Code на этот код:

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

9. В диалоговом окне блока установите System Outputs Function Exit Code в этот код:

{
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 9.136s

11. В отчете о генерации кода просмотрите файл интерфейса rtwdemo_configrpinterface_capi.c. Этот файл инициализирует массивы структур, которые можно использовать для взаимодействия с элементами данных через C API. Для примера в массиве структур 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 для доступа к информации, содержащейся в массивах структур, которые rtwdemo_configrpinterface_capi.c файл C API задает.

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. Функция использует C API, чтобы напечатать значение тестового сигнала. Функция может получить доступ к данным сигнала, является ли тип данных single или double.

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

system('rtwdemo_configrpinterface')

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

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

Сконфигурируйте доступность данных

ЦельФакторы и дополнительная информация
Сконфигурируйте сигналы как доступные и параметры как настраиваемые по умолчанию

Очистите параметр конфигурации модели Signal storage reuse и установите параметр конфигурации Default parameter behavior равным Tunable. Эти настройки препятствуют устранению памяти для сигналов и предотвращают встраивание параметра. Каждые параметры блоков и сигнальная линия появляются в сгенерированном коде как поле структуры. Для получения дополнительной информации об этих структурах данных смотрите, Как сгенерированный код обменивается данными с Окружением и Как сгенерированный код хранит внутренний сигнал, состояние и данные параметра.

Для получения дополнительной информации о Default parameter behavior см. Раздел «Поведение параметра по умолчанию». Для получения дополнительной информации об оптимизации, которая устраняет устройство хранения сигналов, смотрите, Как Сгенерированный код хранит внутренний сигнал, состояние и данные параметра и минимизирует расчеты и хранение для промежуточных результатов на выходах блоков.

Сохраните доступность и настраиваемость элемента данных после выбора оптимизации

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

  • Сконфигурируйте сигналы в редакторе Code Mappings. В редакторе можно задать строение по умолчанию для сигналов, добавить интересующие сигналы к отображениям кода, а затем задать класс памяти для отдельных сигналов к классу памяти по умолчанию или другому классу памяти. Сигналы могут быть названы путем установки Identifier свойство класса памяти.

  • Применить класс памяти, например ExportedGlobal, состояниям и параметрам. Смотрите Строение Генерации кода C для Элементов Интерфейса Модели.

Представление элемента данных как отдельной глобальной переменной в сгенерированном коде

Когда вы отключаете оптимизацию, сигнальные линии, состояния блока и параметры появляются в сгенерированном коде как поля структур. Вы не можете управлять именами структур без Embedded Coder®. Чтобы вместо этого сохранить элемент данных в отдельной глобальной переменной, имя, размещение файла и другие характеристики, которыми можно управлять, примените класс памяти к сигналу, состоянию или Simulink.Parameter объект. Смотрите Строение Генерации кода C для Элементов Интерфейса Модели.

Сгенерируйте стандартизированный интерфейс кода С для доступа к даннымМожно сконфигурировать сгенерированный код таким образом, чтобы он содержал дополнительный код и файлы, чтобы вы могли получить доступ к данным моделям через стандартизированные интерфейсы. Для получения дополнительной информации см. раздел Обмен данными между сгенерированным и Внешним кодом с использованием C API.
Настройки параметров и мониторинг сигналов во время симуляции режима external mode

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

Для получения информации о внешнем режиме смотрите Симуляции Режима external mode для Настройки параметра и Контроля сигналов.

Настройки параметров и мониторинг сигналов с помощью Simulink® Real-Time™

Если у вас есть Simulink Real-Time, можно настроить параметры и контролировать сигналы во время выполнения вашего приложения реального времени. Сделайте сигналы доступными и параметры настраиваемыми путем очистки оптимизации и применения тестовых точек и классов памяти. Смотрите Настройку Параметра в Simulink Real-Time Explorer (Simulink Real-Time).

Ограничения

Для получения информации об ограничениях, которые применяются к настраиваемости параметров в сгенерированном коде, смотрите Ограничения для Настраиваемости Параметров блоков в Сгенерированном Коде.

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте