exponenta event banner

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

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

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

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

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

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

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

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

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

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

Изучение примера модели

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

prepare_rtwdemo_configrpinterface

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

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

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

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

Откройте пример модели, rtwdemo_configrpinterface.

rtwdemo_configrpinterface

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

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

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

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.

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. Другие поля структуры представляют другие параметры блока и переменные рабочей области из модели, включая начальные условия для сигналов и состояний.

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 выберите Интерфейс кода > Сопоставления кодов отдельных элементов.

2. В редакторе сопоставлений кодов проверьте закладку Signals/States.

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

4. Чтобы открыть панель действий, сделайте паузу на многоточии, которое появляется выше или ниже сигнальной линии. Нажмите кнопку Add Signal (Добавить сигнал). В редакторе сопоставлений кодов узел «Сигналы» расширяется и отображает добавленный сигнал.

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. Примените класс хранения по умолчанию для выходов к сигналу, установив для класса хранения значение Model default.

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

6. В модели выберите блок усиления.

7. В инспекторе свойств задайте значение коэффициента усиления для объекта параметра рабочего пространства модели K1.

8. В редакторе «Сопоставления кодов» на вкладке «Параметры» разверните узел «Параметры модели».

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, который представляет тестовый выходной сигнал блока усиления.

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'
                                        */
};

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

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

Скопировать этот пользовательский исходный код в файл с именем 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-файл Logging. Создаваемый исполняемый файл запускается только до момента остановки моделирования (который задается в параметрах конфигурации модели).

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. Добавьте в модель блок «Системные выходы».

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

8. В диалоговом окне «System Outputs block» установите для параметра «System Outputs Function Execution Code» значение «System Outputs Function»

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

Кроме того, для настройки блока «Системные выходы» в командной строке используются следующие команды:

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) описывает выходной сигнал тестовой точки блока усиления в модели.

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 функция. Алгоритм сначала выполняет код, указанный в блоке «Системные выходы».

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 для доступа к информации, содержащейся в массивах структур файла C API rtwdemo_configrpinterface_capi.c определяет.

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

14. Просмотр алгоритма кода в модели step снова функция. В конце функции алгоритм выполняет код, указанный в блоке «Системные выходы». Этот код вызывает функцию 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')

Значения параметров и сигналов отображаются в выходных данных окна команд.

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

Настройка специальных возможностей для данных

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

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

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

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

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

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

  • Применение класса хранения, например ExportedGlobal, к состояниям и параметрам. См. раздел Конфигурация генерации кода C для элементов интерфейса модели.

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

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

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

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

Сведения о внешнем режиме см. в разделе Моделирование внешнего режима для настройки параметров и мониторинга сигналов.

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

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

Ограничения

Сведения об ограничениях, применимых к настраиваемости параметров в сгенерированном коде, см. в разделе Ограничения настройки параметров блоков в сгенерированном коде.

Связанные темы