Внешний код C можно вызывать и интегрировать в модели Simulink ® с помощью функциональных блоков C. Функциональные блоки C позволяют вызывать внешний код C и настраивать интеграцию кода с помощью областей Output Code, Start Code и Terminate Code в диалоговом окне параметров блока. Используйте функциональный блок C для :
Вызовите функции из внешнего кода C и настройте код для моделей Simulink.
Предварительная обработка данных для вызова функции C и постобработка данных после вызова функции.
Укажите другой код для моделирования и создания кода.
Вызовите несколько функций.
Инициализация и работа с постоянными данными, кэшированными в блоке.
Выделение и освобождение памяти.
Используйте блок C Function для вызова внешних алгоритмов C в Simulink, которые требуется изменить. Для вызова одной функции C из модели Simulink используется блок C Caller. Для интеграции динамических систем с непрерывными состояниями или изменениями состояний используется блок S-Function.
В следующих примерах используются блоки C Function для вычисления суммы и среднего значения входных данных.
Начните с создания внешних исходных файлов.
Создание файла заголовка с именем data_array.h.
/* Define a struct called DataArray */
typedef struct DataArray_tag {
/* Define a pointer called pData */
double* pData;
/* Define the variable length */
int length;
} DataArray;
/* Function declaration */
double data_sum(DataArray data);В той же папке создайте новый файл, data_array.c. В этом файле запишите функцию C, которая вычисляет сумму входных чисел.
#include "data_array.h"
/* Define a function that takes in a struct */
double data_sum(DataArray data)
{
/* Define 2 local variables to use in the function */
double sum = 0.0;
int i;
/* Calculate the sum of values */
for (i = 0; i < data.length; i++) {
sum = sum + data.pData[i];
}
/* Return the result to the block */
return sum;
}Создайте новую пустую модель и добавьте блок функции C. Блок функций C находится в библиотеке пользовательских функций браузера библиотеки.
Дважды щелкните блок C Function, чтобы открыть диалоговое окно блока. Нажмите
для открытия диалогового окна «Параметры конфигурации». На панели Цель моделирования определите файл заголовка в разделе Вставить пользовательский код C в сгенерированном: > Файл заголовка.
Определите исходный файл в разделе Дополнительные сведения о построении > Исходные файлы.

Примечание
Чтобы использовать блок C Function в подсистеме For Each или с непрерывным временем выборки, или для оптимизации использования блока при выполнении условной ветви ввода, все пользовательские функции кода, вызываемые блоком, должны быть детерминированными, то есть всегда создавать одни и те же выходы для одних и тех же входов. Определите, какие пользовательские функции кода являются детерминированными, используя функции Детерминированные (Deterministic) и Указать по параметрам функции (Specify by function parameters) на целевой панели Моделирование (Simulation). Если блок ссылается на какие-либо пользовательские глобальные переменные кода, то детерминированные функции должны иметь значение All для использования блока в подсистеме For Each, при выполнении условного входного ответвления или с непрерывным временем выборки.
Пример, показывающий функциональный блок C в подсистеме Для каждой, см. в разделе Использование функционального блока C в каждой подсистеме.
Нажмите кнопку ОК, чтобы закрыть окно Параметры конфигурации (Configuration Parameters).
На панели «Output Code» диалогового окна «C Function block parameters» запишите код, который выполняется блоком во время моделирования. В этом примере внешняя функция C вычисляет сумму. На панели «Код вывода» введите код, вызывающий data_array.c функция для вычисления суммы, затем вычисляет среднее значение.
/* declare the struct dataArr */ DataArray dataArr; /* store the length and data coming in from the input port */ dataArr.pData = &data; dataArr.length = length; /* call the function from the external code to calculate sum */ sum = data_sum(dataArr); /* calculate the mean */ mean = sum / length;
Код, запускаемый в начале моделирования и в конце моделирования, можно указать на панелях Начальный код (Start Code) и Завершить код (Terminate Code).
Таблица Символы (Symbols) используется для определения символов, используемых во внешнем коде C. Добавьте или удалите символ с помощью кнопок «Добавить» и «Удалить». Определите все символы, используемые в областях Output Code, Start Code и Terminate Code, для обеспечения правильного отображения портов.

В таблице Символы (Symbols) определите следующее.
Имя - имя символа в исходном коде.
Область - объем символов и порядок их отображения. Область действия символа можно изменить в любое время.
Input - Символ ввода в блок C Function.
Output - Выходной символ в блок C Function.
InputOutput - Определите символ как входной и выходной в блоке C Function.
Используйте InputOutput для сопоставления входных данных, передаваемых указателем в коде C. Порты, созданные с помощью InputOutput области имеют одинаковые имена для портов ввода и вывода. InputOutput позволяет повторно использовать буфер для портов ввода и вывода. Буфер повторного использования может оптимизировать использование памяти и улучшить моделирование кода и эффективность генерации кода в зависимости от размера сигнала и компоновки блока. Ограничения включают:
InputOutput символ не может использоваться в Start и Terminate код.
InputOutput порт не поддерживает void* тип данных.
InputOutput порт не поддерживает size() выражения.
Persistent - Определите символ как постоянные данные.
Можно определить указатель на пустоту с помощью Persistent область в блоке C Function. Указатель void - это указатель, который может хранить данные любого типа, созданные или выделенные пользователем.
Constant - определение символа как константы с помощью числовых выражений или значений размера.
Parameter - определение символа в качестве параметра. Имя параметра определяется меткой символа.
Метка - метка символа. Для символов с их областью видимости Input или Output, эта метка отображается как имя порта в блоке. Для символов с их областью видимости Parameter, эта метка является меткой, которая отображается в маске параметра блока. Невозможно определить метку для Persistent символы. Если область действия Constant, метка - это константное выражение.
Тип (Type) - тип данных символа. Выберите тип данных из раскрывающегося списка или укажите пользовательский тип данных.
Использование пользовательского типа, например Simulink.Bus, Перечисление симулинков или Simulink.AliasType , который не имеет определения внешнего заголовка, связанного с блоком C Function, правильно задайте тип в таблице Symbol.
Размер - размер данных символа. Блок C Function поддерживает только скаляры и векторы. Матрицы и массивы с более высокой размерностью не поддерживаются. Для определения размера вывода можно использовать выражение размера. Использовать -1 для наследования размера.
Порт - для входных и выходных символов, Port указывает индекс порта в блоке данных символа. Для обозначений параметров: Port указывает порядок отображения символа в маске параметра блока.
Закройте диалоговое окно параметров блока. После заполнения данных в таблице блок C Function теперь имеет один входной порт и два выходных порта с метками, указанными в таблице.
Добавьте блок константы в холст Simulink, который будет вводиться в блок C Function. В блоке «Константа» создайте случайный массив строк со 100 элементами. Чтобы отобразить результаты, присоедините блоки отображения к выходам блока C Function.

Можно вызвать это подмножество функций C Math Library из блока C Function:
abs | acos | asin | atan | atan2 | ceil |
cos | cosh | exp | fabs | floor | fmod |
labs | ldexp | log | log10 | pow | sin |
sinh | sqrt | tan | tanh |
При вызове этих функций применяется двойная точность, если все входные аргументы явно не являются одной точностью. При несовпадении типов приведение входных аргументов к ожидаемому типу заменяет исходные аргументы. Например, при вызове sin функция с целым аргументом, приведением входного аргумента к числу с плавающей запятой типа double заменяет исходный аргумент.
Если требуется вызвать другие функции библиотеки C, которые не перечислены выше, создайте функцию внешней оболочки, которая вызывает функцию библиотеки C.
abs, fabs, и labs ФункцияТолкование abs, fabs, и labs функции в блоке C Function выходят за рамки стандартной версии C и включают целочисленные аргументы и аргументы с плавающей запятой:
Если x - целое число, стандартная функция C применяется к x, или abs(x).
Если x является двойным, стандартная функция C labs относится к x, или labs(x).
Если x является одиночным, стандартная функция C fabs относится к x, или fabs(x).
Вызов функции должен вызывать правильный CRL на основе типа данных, передаваемых в функцию. Если CRL не указан, вызов функции должен вызывать библиотеку, зависящую от типа. CRL для C99 генерирует специфичную для типа функцию. Например:
| Тип передан | Вызов генерации кода |
|---|---|
sin(doubleIn) | sin(doubleIn) |
sin(floatIn) | sinf(floatIn) |
Можно указать различные выходные коды для моделирования и генерации кодов для блока C Function путем определения MATLAB_MEX_FILE. Например, для указания кода, выполняемого только во время моделирования модели, используется следующее.
#ifdef MATLAB_MEX_FILE /* Enter Sim Code */ #else /* Enter code generation code */ #endif
В целях создания кода, если у вас нет внешнего файла заголовка с объявлением функции (например, драйвера устройства, специфичного для цели), которую вы хотите вызвать из блока C Function, вы можете включить объявление с правильной подписью в панель Output Code блока. Это действие создает вызов ожидаемой функции при создании кода, как в следующем примере:
#ifndef MATLAB_MEX_FILE extern void driverFcnCall(int16_T in, int16_T * out); driverFcnCall(blockIn, &blockOut); #endif
При моделировании модели, содержащей пользовательский код C или C++, можно выполнить пользовательский код в отдельном процессе вне MATLAB ®. Этот параметр может быть полезен при отладке пользовательского кода. При выполнении в отдельном процессе проблемы с пользовательским кодом не приводят к аварийному завершению работы MATLAB, что упрощает отладку и устранение таких проблем. Проблемы могут возникнуть из-за непредвиденных исключений в пользовательском коде или ошибок в интерфейсе между Simulink и пользовательским кодом. Дополнительные сведения см. в разделе Моделирование пользовательского кода в отдельном процессе.