Обмен данными между сгенерированным и внешним кодом с использованием C API

Некоторый Simulink® Coder™ приложения должны взаимодействовать с сигналами, состояниями, входами/выходами корневого уровня или параметрами в сгенерированном коде для модели. Для примера приложения калибровки контролируют и изменяют параметры. Контроли сигналов или приложения регистрации данных взаимодействуют с входными/выходными данными сигнала, состояния и корневого уровня. Используя Simulink Coder C API, можно создать целевые приложения, которые регистрируют сигналы, состояния и входы/выходные параметры корневого уровня, отслеживают сигналы, состояния и входные/выходные параметры корневого уровня и настраивают параметры, в то время как сгенерированный код выполняется.

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

Чтобы начать с примера, смотрите Использование C API для доступа к сигналам модели и состояниям или Использование C API для доступа к параметрам модели.

Сгенерированные файлы API на C

Когда вы конфигурируете модель, чтобы использовать API C, генератор кода Simulink Coder генерирует два дополнительных файла, model_capi.c (или .cpp) и model_capi.h, где model - имя модели. Генератор кода помещает два файла C API в папку сборки на основе настроек в диалоговом окне Параметров конфигурации. Файл кода C API содержит информацию о глобальных выходных сигналах блоков, состояниях, входах/выходах корневого уровня и глобальных параметрах, определенных в исходном коде сгенерированного кода. Заголовочный файл C API является файлом заголовка интерфейса между исходным кодом модели и сгенерированным API C. Для создания приложения можно использовать информацию из этих файлов C API. Среди сгенерированных файлов можно выделить файлы, показанные на следующем рисунке.

Сгенерированные файлы с выбранным C API

Примечание

Когда вы конфигурируете генератор кода, чтобы создать код, который включает поддержку интерфейса C API и логгирование данных, генератор кода может включать текст для имен блоков в пути блоков, регистрируемых в файлах C API model_capi.c (или .cpp) и model_capi.h. Если текст включает символы, которые не представлены в кодировке набора символов для модели, генератор кода заменяет символы XML-переходными последовательностями. Например, генератор кода заменяет японскую полноразмерную букву Катаканы ア на выходную последовательность ア. Для получения дополнительной информации смотрите Интернационализация и Генерация кода.

Сгенерируйте файлы API на C

Чтобы сгенерировать файлы C API для вашей модели:

  1. Выберите интерфейс C API для вашей модели. Существует два способа выбора интерфейса C API для вашей модели, как описано в следующих разделах.

  2. Сгенерируйте код для вашей модели.

После генерации кода можно изучить файлы model_capi.c (или .cpp) и model_capi.h в папке сборки модели.

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

  1. Откройте модель и диалоговое окно Параметры конфигурации.

  2. На панели Code Generation > Interface в подгруппе Data exchange interface выберите одну или несколько C API опции. На основе выбранных опций в сгенерированном коде C API появится поддержка доступа к сигналам, параметрам, состояниям и вводам-выводам корневого уровня.

    • Если вы хотите сгенерировать код C API для глобальных выходных сигналов блоков, выберите Generate C API for: signals.

    • Если вы хотите сгенерировать код C API для параметров глобальных блоков, выберите Generate C API for: parameters.

    • Если вы хотите сгенерировать код C API для дискретных и непрерывных состояний, выберите Generate C API for: states.

    • Если вы хотите сгенерировать код C API для входов и выходов корневого уровня, выберите Generate C API for: root-level I/O.

Выберите C API из командной строки

Из MATLAB® командная строка, вы можете использовать set_param функция для выбора или удаления параметров конфигурации модели C API. В командной строке MATLAB введите одну или несколько из следующих команд, где modelname - имя вашей модели.

Чтобы выбрать Generate C API for: signals, введите:

set_param('modelname','RTWCAPISignals','on')

Чтобы удалить Generate C API for: signals, введите:

set_param('modelname','RTWCAPISignals','off')

Чтобы выбрать Generate C API for: parameters, введите:

set_param('modelname','RTWCAPIParams','on')

Чтобы удалить Generate C API for: parameters, введите:

set_param('modelname','RTWCAPIParams','off')

Чтобы выбрать Generate C API for: states, введите:

set_param('modelname','RTWCAPIStates','on')

Чтобы удалить Generate C API for: states, введите:

set_param('modelname','RTWCAPIStates','off')

Чтобы выбрать Generate C API for: root-level I/O, введите:

set_param('modelname','RTWCAPIRootIO','on')

Чтобы удалить Generate C API for: root-level I/O, введите:

set_param('modelname','RTWCAPIRootIO','off')

Описание файлов API на C

Сведения о файлах API на C

The model_capi.c (или .cpp) файл предоставляет внешние приложения с последовательным интерфейсом для данных моделей. В зависимости от настроек строения, данные могут быть сигналом, состоянием, входом или выходом корневого уровня или параметром. В этом документе термин data item относится либо к сигналу, состоянию, входу или выходу корневого уровня, либо к параметру. C API использует структуры, которые обеспечивают интерфейс со свойствами элемента данных. Интерфейс упаковывает свойства каждого элемента данных в структуре данных. Если модель содержит несколько элементов данных, интерфейс генерирует массив структур данных. Представители структуры данных сопоставлены со свойствами данных.

Для взаимодействия с элементами данных приложению требуются следующие свойства для каждого элемента данных:

  • Имя

  • Путь блока

  • Номер порта (только для сигналов и входов/выходов корневого уровня)

  • Адрес

  • Информация о типе данных: собственный тип данных, размер данных, сложность и другие атрибуты

  • Информация о размерностях: количество строк, количество столбцов и ориентация данных (скаляр, вектор, матрица или n-размерность)

  • Информация с фиксированной точкой: наклон, смещение, тип шкалы, размер слова, экспонента и другие атрибуты

  • Шаг расчета информация (только для сигналов, состояний и входов/выходов корневого уровня): Шаг расчета, идентификатор задачи, системы координат

Как показано на следующем рисунке, свойства элемента А данных, для примера, расположены в структуре DS_A данных. Свойства элемента данных B расположены в DS_B структуры данных.

Некоторые значения свойств могут быть уникальными для каждого элемента данных, и существуют некоторые значения свойств, которые могут совместно использоваться несколькими элементами данных. Например, имя имеет уникальное значение для каждого элемента данных. Интерфейс помещает уникальные значения свойств непосредственно в структуру для элемента данных. Значение имени элемента данных A находится в DS_A, а значение имени элемента данных B - в DS_B.

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

Рисунок показывает три сигнала. signal1 и signal2 совместно использовать тот совпадающий тип данных, double. Вместо определения значения этого типа данных в каждой структуре сигнальных данных интерфейс обеспечивает только значение индекса, 0, в структуре. "double" описывается записью 0 в rtDataTypeMap массив, на который ссылаются оба сигнала. Кроме того, значения свойств могут быть разделены между сигналами, состояниями, входами/выходами корневого уровня и параметрами, поэтому состояния, входы/выходные параметры корневого уровня и параметры также могут ссылаться на double запись в rtDataTypeMap массив. Это повторное использование информации уменьшает размер памяти сгенерированного интерфейса.

Массивы структур, сгенерированные в файлах API на C

Как и в случае с типом данных, интерфейс преобразует другие общие свойства (такие как адрес, размерность, масштабирование с фиксированной точкой и шаг расчета) в отдельные структуры и предоставляет индекс в структуре для элемента данных. Полный список определений структур см. в файле matlabroot/ rtw/c/src/rtw_capi.h. Этот файл также описывает каждый представителя в структуре. Массивы структур, сгенерированные в model_capi.c (или .cpp) файлы имеют типы структур, определенные в rtw_capi.h файл. Вот краткое описание массивов структур, сгенерированных в model_capi.c (или .cpp):

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

  • rtBlockParameters - массив структур, который содержит информацию о настраиваемых параметрах блоков в модели по имени блоков и имени параметров. Каждый элемент массива имеет тип struct rtwCAPI_BlockParameters. Представители этой структуры предоставляют имя параметра, путь блока, адрес и индексы типу данных, размерности и массивам структур с фиксированной точкой.

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

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

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

  • rtModelParameters - массив структур, содержащий информацию о переменных рабочего места, которые являются одним или несколькими блоками или Stateflow® Графики в модель-ссылку следующими параметрами блоков. Каждый элемент массива имеет тип данных rtwCAPI_ModelParameters. Представители этой структуры предоставляют имя переменной, адрес и индексы типу данных, размерности и массивам структур с фиксированной точкой.

  • rtDataAddrMap является массивом базовых адресов сигналов, состояний, входов/выходов корневого уровня и параметров, которые появляются в rtBlockSignals, rtBlockParameters, rtBlockStates, и rtModelParameters массивы. Каждый элемент rtDataAddrMap массив является указателем на void (void*).

  • rtDataTypeMap - массив структур, содержащий информацию о различных типах данных в модели. Каждый элемент этого массива имеет тип struct rtwCAPI_DataTypeMap. Представители этой структуры предоставляют имя типа данных, размер типа данных и информацию о том, являются ли данные сложными или нет.

  • rtDimensionMap - массив структур, содержащий информацию о различных размерностях данных в модели. Каждый элемент этого массива имеет тип struct rtwCAPI_DimensionMap. Представители этой структуры предоставляют информацию о количестве измерений в данных, ориентации данных (будь то скаляр, вектор или матрица) и фактических размерностях данных.

  • rtFixPtMap - массив структур, который содержит информацию с фиксированной точкой о сигналах, состояниях, входах/выходах корневого уровня и параметрах. Каждый элемент этого массива имеет тип struct rtwCAPI_FixPtMap. Представители этой структуры предоставляют информацию о масштабировании данных, смещении, экспоненте и о том, подписаны ли данные с фиксированной точкой. Если модель не имеет данных с фиксированной точкой (сигнал, состояние, вход/выход корневого уровня или параметр), программное обеспечение Simulink Coder присваивает NULL или нули значений к элементам rtFixPtMap массив.

  • rtSampleTimeMap - массив структур, который содержит информацию дискретизации о глобальных сигналах, состояниях и входах/выходах корневого уровня в модели. (Этот массив не содержит информации о параметрах.) Каждый элемент этого массива имеет тип struct rtwCAPI_SampleTimeMap. Представители этой структуры предоставляют информацию о периоде дискретизации, смещении и о том, основаны ли данные на кадре или на выборке.

Сгенерируйте пример C API Файлов

Подтопики Сигналы API C, Состояния API C, Входы и выходы корневого уровня C API и Параметры API C обсуждают сгенерированные структуры API C с помощью модели примера rtwdemo_capi. Чтобы сгенерировать код из модели примера, выполните следующее:

  1. Откройте модель, нажав на rtwdemo_capi ссылка выше или путем ввода rtwdemo_capi в командной строке MATLAB.

  2. Если вы хотите сгенерировать структуры C API для входов/выходов корневого уровня в rtwdemo_capi, выберите Generate C API for: root-level I/O параметра конфигурации модели.

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

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

Примеры кода C API в следующих подтемах сгенерированы с C в качестве целевого языка.

Эта модель имеет трёх глобальных блоков выходы сигнала, которые появятся в сгенерированном коде C API:

  • top_sig1, которая является тестовой точкой на выходе блока Gain1 в верхней модели

  • sig2_eg, которая появляется в верхней модели и определяется в базовом рабочем пространстве как Simulink.Signal объект, имеющий класс памяти ExportedGlobal

  • bot_sig1, который появляется в ссылочной модели rtwdemo_capi_bot и определяется как Simulink.Signal объект, имеющий класс памяти Model default

Модель также имеет два дискретных состояния, которые появятся в сгенерированном коде C API:

  • top_state, который определяется для блока Delay1 в верхней модели

  • bot_state, который определен для блока Дискретный Фильтр в ссылке модели

Модель имеет входы/выходные параметры корневого уровня, которые появятся в коде, сгенерированном C API, если вы выбираете параметр конфигурации модели Generate C API for: root-level I/O:

  • Четыре входа корневого уровня, In1 через In4

  • Шесть выходов корневого уровня, Out1 через Out6

Кроме того, модель имеет пять глобальных параметров блоков, которые появятся в сгенерированном С API коде:

  • Kp (верхняя часть Gain1 блочная и ссылочная модели Gain2 блок общего ресурса)

  • Ki (ссылочная модель Gain3 блок)

  • p1 (интерполяционная таблица lu1d)

  • p2 (интерполяционная таблица lu2d)

  • p3 (интерполяционная таблица lu3d)

Сигналы API на C

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

Вот раздел кода в rtwdemo_capi_capi.c который предоставляет информацию о сигналах C API для верхней модели в rtwdemo_capi:

/* Block output signal information */
static const rtwCAPI_Signals rtBlockSignals[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 0, 0, "rtwdemo_capi/Gain1",
    "top_sig1", 0, 0, 0, 0, 0 },

  { 1, 0, "rtwdemo_capi/lu2d",
    "sig2_eg", 0, 0, 1, 0, 0 },

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

Примечание

Чтобы лучше изучить код, читайте комментарии в файле. Например, заметьте комментарий, который начинается с третьей линии в предыдущем коде. В этом комментарии перечислены представители rtwCAPI_Signals структура, по порядку. Это сообщает вам порядок, в котором назначенные значения для каждого представителя появляются для сигнала. В этом примере комментарий говорит вам, что signalName является четвертым представителем структуры. Следующие линии описывают первый сигнал:

  { 0, 0, "rtwdemo_capi/Gain1",
    "top_sig1", 0, 0, 0, 0, 0 },

Из этих линий вы выводите, что имя первого сигнала top_sig1.

Каждый элемент массива, кроме последнего, описывает один выходной порт для блочного сигнала. Конечный элемент массива является дозорным, со всеми элементами, установленными на null значений. Например, исследуйте второй сигнал, описанный следующим кодом:

  { 1, 0, "rtwdemo_capi/lu2d",
    "sig2_eg", 0, 0, 1, 0, 0 },

Этот сигнал, названный sig2_eg, является выход сигналом первого порта блока rtwdemo_capi/lu2d. (Этот порт является первым портом, поскольку нулевой индекс для portNumber во второй линии присваивается значение 0.)

Адрес этого сигнала задается addrMapIndex, который в этом примере отображается на первой линии следующим образом 1. Это обеспечивает индекс в rtDataAddrMap массив, найденный позже в rtwdemo_capi_capi.c:

/* Declare Data Addresses statically */
static void* rtDataAddrMap[] = {
  &rtwdemo_capi_B.top_sig1,            /* 0: Signal */
  &sig2_eg[0],                         /* 1: Signal */
  &rtwdemo_capi_DWork.top_state,       /* 2: Discrete State */
  &rtP_Ki,                             /* 3: Model Parameter */
  &rtP_Kp,                             /* 4: Model Parameter */
  &rtP_p1[0],                          /* 5: Model Parameter */
  &rtP_p2[0],                          /* 6: Model Parameter */
  &rtP_p3[0],                          /* 7: Model Parameter */
};

Индекс 1 указывает на второй элемент в rtDataAddrMap массив. Из rtDataAddrMap массив, можно сделать вывод, что адрес этого сигнала &sig2_eg[0].

Этот уровень косвенности поддерживает несколько образцы кода одной модели. В нескольких образцах информация о сигнале остается постоянной, за исключением адреса. В этом случае модель является единичным образцом. Поэтому rtDataAddrMap объявляется статически. Если вы принимаете решение сгенерировать повторно используемый код, генерируется функция initialize, которая инициализирует адреса динамически по образцам. Для получения дополнительной информации о генерации повторно используемого кода смотрите Configure C Code Generation for Model Entry-Point Functions и смотрите Configure Code Reuse Support.

The dataTypeIndex задает индекс в rtDataTypeMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий тип данных сигнала:

/* Data Type Map - use dataTypeMapIndex to access this structure */
static const rtwCAPI_DataTypeMap rtDataTypeMap[] = {
  /* cName, mwName, numElements, elemMapIndex, dataSize, slDataId, *
   * isComplex, isPointer */
  { "double", "real_T", 0, 0, sizeof(real_T), SS_DOUBLE, 0, 0 }
};

Потому что индекс 0 для sig2_egиндекс указывает на первый структурный элемент массива. Можно сделать вывод, что тип данных сигнала double. Значение isComplex является 0, что указывает на то, что сигнал не является комплексным. Вместо предоставления информации о типах данных непосредственно в rtwCAPI_Signals вводят структуру, уровень опосредования. Опосредование позволяет нескольким сигналам, которые имеют один и тот совпадающий тип данных, указывать на одну структуру карты, сохраняя память для каждого сигнала.

The dimIndex (индекс размерностей) обеспечивает индекс в rtDimensionMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий размерности сигнала. Потому что этот индекс 1 для sig2_eg, индекс указывает на второй элемент в rtDimensionMap массив:

/* Dimension Map - use dimensionMapIndex to access elements of ths structure*/
static const rtwCAPI_DimensionMap rtDimensionMap[] = {
  /* dataOrientation, dimArrayIndex, numDims, vardimsIndex */
  { rtwCAPI_SCALAR, 0, 2, 0 },

  { rtwCAPI_VECTOR, 2, 2, 0 },
...
};

Из этой структуры можно сделать вывод, что это нескалярный сигнал, имеющий размерность 2. The dimArrayIndex значение, 2, обеспечивает индекс в rtDimensionArray, найденный позже в rtwdemo_capi_capi.c:

/* Dimension Array- use dimArrayIndex to access elements of this array */
static const uint_T rtDimensionArray[] = {
  1,                                   /* 0 */
  1,                                   /* 1 */
  2,                                   /* 2 */
...
};

The fxpIndex (индекс с фиксированной точкой) обеспечивает индекс в rtFixPtMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий информацию о сигнале с фиксированной точкой. Ваш код может использовать информацию масштабирования, чтобы вычислить реальное значение сигнала, используя уравнение V=SQ+B, где V является значением «реального мира» (то есть основа -10), S является заданным пользователем наклоном, Q является «квантованным значением фиксированной точки» или «сохраненным целым числом», а B является заданным пользователем смещением. Для получения дополнительной информации смотрите Масштабирование (Fixed-Point Designer).

Потому что этот индекс 0 для sig2_egсигнал не имеет информации о фиксированной точке. Нулевой индекс карты с фиксированной точкой означает, что сигнал не имеет информации о фиксированной точке.

The sTimeIndex (шаг расчета) обеспечивает индекс к rtSampleTimeMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий информацию задачи о сигнале. Если вы записываете мультирейт-сигналы или условно выполняемые сигналы, информация о дискретизации может быть полезной.

Примечание

model_capi.c (или .cpp) включает rtw_capi.h. Исходный файл, который ссылается на rtBlockSignals массив также должен включать rtw_capi.h.

Состояния API на C

The rtwCAPI_States структура захватывает информацию о состоянии, включая имя состояния, адрес, путь блока, тип (непрерывный или дискретный), информацию о типе данных, информацию о размерностях, информацию о фиксированной точке и информацию о шаге расчета.

Вот раздел кода в rtwdemo_capi_capi.c который предоставляет информацию о состояниях C API для верхней модели в rtwdemo_capi:

/* Block states information */
static const rtwCAPI_States rtBlockStates[] = {
  /* addrMapIndex, contStateStartIndex, blockPath,
   * stateName, pathAlias, dWorkIndex, dataTypeIndex, dimIndex,
   * fixPtIdx, sTimeIndex, isContinuous
   */
  { 2, -1, "rtwdemo_capi/Delay1",
    "top_state", "", 0, 0, 0, 0, 0, 0 },

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

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

  { 2, -1, "rtwdemo_capi/Delay1",
    "top_state", "", 0, 0, 0, 0, 0, 0 },

Это состояние, назовите top_state, определяется для блока rtwdemo_capi/Delay1. Значение isContinuous равен нулю, что указывает на то, что состояние дискретно, а не непрерывно. Другие поля соответствуют одноименным эквивалентам сигнала, описанным в сигналах C API, следующим образом:

  • Адрес сигнала задается addrMapIndex, который, в этом примере, является 2. Это индекс в rtDataAddrMap массив, найденный позже в rtwdemo_capi_capi.c. Поскольку индекс основан на нуле, 2 соответствует третьему элементу в rtDataAddrMap, что &rtwdemo_capi_DWork.top_state.

  • The dataTypeIndex задает индекс в rtDataTypeMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий тип данных параметра. Значение 0 соответствует двойному, некомплексному параметру.

  • The dimIndex (индекс размерностей) обеспечивает индекс в rtDimensionMap массив, найденный позже в rtwdemo_capi_capi.c. Значение 0 соответствует первой записи, которая { rtwCAPI_SCALAR, 0, 2, 0 }.

  • The fixPtIndex (индекс с фиксированной точкой) обеспечивает индекс в rtFixPtMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий информацию о параметре с фиксированной точкой. Как и с соответствующим атрибутом сигнала, нулевой индекс карты с фиксированной точкой означает, что параметр не имеет информации о фиксированной точке.

Входы и выходные параметры уровня корня API на выходы

The rtwCAPI_Signals структура захватывает входную/выходную информацию корневого уровня, включая имя ввода/вывода, адрес, путь блока, номер порта, информацию о типе данных, информацию о размерностях, информацию фиксированной точки и информацию о шаге расчета. (Эта структура также используется для блочных выходных сигналов, как описано ранее в C API Signals.)

Вот раздел кода в rtwdemo_capi_capi.c который предоставляет информацию о входах/выходах корневого уровня C API для верхней модели в rtwdemo_capi:

/* Root Inputs information */
static const rtwCAPI_Signals rtRootInputs[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 3, 0, "rtwdemo_capi/In1",
    "", 1, 0, 0, 0, 0 },

  { 4, 0, "rtwdemo_capi/In2",
    "", 2, 0, 0, 0, 0 },

  { 5, 0, "rtwdemo_capi/In3",
    "", 3, 0, 0, 0, 0 },

  { 6, 0, "rtwdemo_capi/In4",
    "", 4, 0, 0, 0, 0 },

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

/* Root Outputs information */
static const rtwCAPI_Signals rtRootOutputs[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 7, 0, "rtwdemo_capi/Out1",
    "", 1, 0, 0, 0, 0 },

  { 8, 0, "rtwdemo_capi/Out2",
    "", 2, 0, 0, 0, 0 },

  { 9, 0, "rtwdemo_capi/Out3",
    "", 3, 0, 0, 0, 0 },

  { 10, 0, "rtwdemo_capi/Out4",
    "", 4, 0, 0, 0, 0 },

  { 11, 0, "rtwdemo_capi/Out5",
    "sig2_eg", 5, 0, 1, 0, 0 },

  { 12, 0, "rtwdemo_capi/Out6",
    "", 6, 0, 1, 0, 0 },

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

Для получения информации о интерпретации значений в rtwCAPI_Signals структуру см. в предыдущем разделе C API Signals.

Параметры API на C

The rtwCAPI_BlockParameters и rtwCAPI_ModelParameters структуры захватывают информацию о параметре, включая имя параметра, путь блока (для параметров блоков), адрес, информацию о типе данных, информацию о размерностях и информацию о фиксированной точке.

The rtModelParameters массив содержит записи для переменных рабочей области, которые ссылаются как настраиваемые параметры блока Simulink или данные Stateflow возможностей. Для примера настраиваемые параметры включают Simulink.Parameter объекты, которые используют класс памяти, отличный от Auto. Программное обеспечение Simulink Coder присваивает только свои элементы NULL или нулевые значения при отсутствии таких данных.

Настройка, которую вы выбираете для параметра конфигурации модели Default parameter behavior определяет, как информация генерируется в rtBlockParameters массив в model_capi.c (или .cpp).

  • Если вы задаете Default parameter behavior Tunable, а rtBlockParameters массив содержит запись для каждого изменяемого параметра каждого блока в модели. Однако, если вы используете переменный MATLAB или настраиваемый параметр, чтобы задать параметры блоков, параметры блоков не появляется в rtBlockParameters. Вместо этого переменный или настраиваемый параметр появляется в rtModelParameters.

  • Если вы задаете Default parameter behavior Inlined, а rtBlockParameters массив пуст. Программное обеспечение Simulink Coder присваивает только свои элементы NULL или нулевые значения.

Последний представитель каждого массива является часовым, все элементы имеют значения null.

Вот rtBlockParameters массив, который генерируется по умолчанию в rtwdemo_capi_capi.c:

/* Individual block tuning is not valid when inline parameters is *
 * selected. An empty map is produced to provide a consistent     *
 * interface independent  of inlining parameters.                 *
 */
static const rtwCAPI_BlockParameters rtBlockParameters[] = {
  /* addrMapIndex, blockPath,
   * paramName, dataTypeIndex, dimIndex, fixPtIdx
   */
  {
    0, (NULL), (NULL), 0, 0, 0
  }
};

В этом примере генерируется только конечный элемент дозорного массива со всеми представителями структуры rtwCAPI_BlockParameters установлено на NULL и нулевые значения. Это связано с тем, что Default parameter behavior установлено на Inlined по умолчанию для rtwdemo_capi пример модели. Если вы задаете Default parameter behavior Tunable, параметры блоков сгенерированы в rtwCAPI_BlockParameters структура. Однако переменный MATLAB и настраиваемые параметры появляются в rtwCAPI_ModelParameters структура.

Вот rtModelParameters массив, который генерируется по умолчанию в rtwdemo_capi_capi.c:

/* Tunable variable parameters */
static const rtwCAPI_ModelParameters rtModelParameters[] = {
  /* addrMapIndex, varName, dataTypeIndex, dimIndex, fixPtIndex */
  { 2, TARGET_STRING("Ki"), 0, 0, 0 },

  { 3, TARGET_STRING("Kp"), 0, 0, 0 },

  { 4, TARGET_STRING("p1"), 0, 2, 0 },

  { 5, TARGET_STRING("p2"), 0, 3, 0 },

  { 6, TARGET_STRING("p3"), 0, 4, 0 },

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

В этом примере rtModelParameters массив содержит записи для каждой переменной, которая упоминается как настраиваемый параметр Блока Simulink.

Для примера, varName (имя переменной) четвертого параметра p2. Другие поля соответствуют одноименным эквивалентам сигнала, описанным в сигналах C API, следующим образом:

  • Адрес четвертого параметра задается как addrMapIndex, который, в этом примере, является 5. Это индекс в rtDataAddrMap массив, найденный позже в rtwdemo_capi_capi.c. Поскольку индекс основан на нуле, 5 соответствует шестому элементу в rtDataAddrMap, что rtP_p2.

  • The dataTypeIndex задает индекс в rtDataTypeMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий тип данных параметра. Значение 0 соответствует двойному, некомплексному параметру.

  • The dimIndex (индекс размерностей) обеспечивает индекс в rtDimensionMap массив, найденный позже в rtwdemo_capi_capi.c. Значение 3 соответствует четвертой записи, которая { rtwCAPI_MATRIX_COL_MAJOR, 6, 2, 0 }.

  • The fixPtIndex (индекс с фиксированной точкой) обеспечивает индекс в rtFixPtMap массив, найденный позже в rtwdemo_capi_capi.c, указывающий информацию о параметре с фиксированной точкой. Как и с соответствующим атрибутом сигнала, нулевой индекс карты с фиксированной точкой означает, что параметр не имеет информации о фиксированной точке.

Для получения дополнительной информации о настраиваемом параметре памяти в сгенерированном коде смотрите, Как Сгенерированный код хранит Внутренний сигнал, Состояние и Данные параметра.

Сопоставьте структуры данных API C с rtModel

Структура данных модели реального времени инкапсулирует данные модели и связанную с ней информацию, которая полностью описывает модель. Когда вы выбираете функцию C API и генерируете код, генератор кода Simulink Coder добавляет другого представителя в структуру данных модели реального времени, сгенерированную в model.h:

/*
 * DataMapInfo:
 * The following substructure contains information regarding
 * structures generated in the model's C API.
 */
struct {
  rtwCAPI_ModelMappingInfo mmi;
} DataMapInfo;

Этот представитель определяет mmi (для информации отображения модели) типа struct rtwCAPI_ModelMappingInfo. Конструкция расположена в matlabroot/ rtw/c/src/rtw_modelmap.h. The mmi подструктура определяет интерфейс между моделью и файлами API C. Более конкретно, представители mmi сопоставить структуру данных модели реального времени со структурами в model_capi.c (или .cpp).

Инициализация значений mmi представители массивов завершают отображение, как показано на Map Model to C API Arrays of Structures. Каждый представитель указывает на один из массивов структур в сгенерированном файле C API. Для примера адрес rtBlockSignals массив структур выделяется первому представителю mmi подструктура в model.c (или .cpp), используя следующий код в rtw_modelmap.h файл:

/* signals */
struct {
    rtwCAPI_Signals const *signals;     /* Signals Array */
    uint_T                numSignals;   /* Num Signals   */
    rtwCAPI_Signals const *rootInputs;  /* Root Inputs array */
    uint_T               numRootInputs; /* Num Root Inputs  */
    rtwCAPI_Signals const *rootOutputs; /* Root Outputs array */
    uint_T               numRootOutputs;/* Num Root Outputs  */
} Signals;

Модель инициализирует функцию в model.c (или .cpp) выполняет инициализацию путем вызова функции инициализации C API. Например, следующий код генерируется в функции инициализации модели, например, модели rtwdemo_capi:

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

Сопоставьте модель с массивами структур API на C

Примечание

Этот рисунок приводит массивы в том порядке, в котором их структуры появляются rtw_modelmap.h, который немного отличается от их сгенерированного порядка в model_capi.c.

Сгенерируйте файл определения данных API C для обмена данными с целевой системой

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

Откройте модель примера

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

open_system('rtwdemo_capi');

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

1. Настройте протокол клиента/сервера (такой как TCP/IP или двухпортовое соединение памяти) между вашим компьютером разработчика и целевым компьютером.

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

3. Сконфигурируйте элементы данных, к которым необходимо получить доступ с помощью API C с адресуемыми классами памяти.

Настройки строения API для верхней части и моделей-ссылок должны совпадать.

Генератор кода помещает интерфейс C API в файл model_capi.c. В зависимости от настроек строения данные могут представлять сигналы, состояния, параметры и вводы-выводы корневого уровня, сконфигурированные с адресуемыми классами памяти. Файл включает структуры, которые обеспечивают интерфейс со свойствами данных.

Ограничения API на C

Функция C API имеет следующие ограничения.

  • API C не поддерживает следующие значения для CodeFormat Переменная TLC:

    • S-Function

    • Accelerator_S-Function (для ускоренной симуляции)

  • Для целей на основе ERT, API C требует, чтобы поддержка кода с плавающей точкой была включена.

  • Выходные сигналы локальных блоков не поддерживаются.

  • Локальные параметры Stateflow не поддерживаются.

  • Следующие пользовательские объекты класса памяти не поддерживаются:

    • Объекты без пакета csc_registration файл

    • Сгруппированные пользовательские классы памяти

    • Объекты, заданные при помощи макросов

    • BitField объекты

    • FileScope объекты

  • Настраиваемое размещение данных отключается при использовании C API. Интерфейс ищет глобальные данные объявление в model.h и model_private.h. Объявления, помещенные в любой другой файл с помощью настроенного размещения данных, приводят к тому, что код не компилируется.

Примечание

Пользовательские объекты класса памяти работают в генерации кода, только если вы используете целевой файл системы ERT и очищаете параметр конфигурации <reservedrangesplaceholder0> модели.

Похожие темы