Вызовите и интегрируйте внешние алгоритмы C в Simulink Используя блоки C Function

Можно вызвать и интегрировать внешний код С в Simulink® модели с помощью блоков C Function. блоки C Function позволяют вам вызывать внешний код С и настраивать интегрирование вашего кода с помощью Output Code, Start Code и панелей Terminate Code в диалоговом окне параметров блоков. Используйте блок C Function для:

  • Вызовите функции от внешнего кода С и настройте код для своих моделей Simulink.

  • Предварительно обработайте данные, чтобы вызвать функцию C и постобработать данные после вызывания функции.

  • Задайте различный код для симуляции и генерации кода.

  • Вызовите несколько функций.

  • Инициализируйте и работайте с персистентными данными, кэшируемыми в блоке.

  • Выделите и освободите память.

Используйте блок C Function, чтобы вызвать внешние алгоритмы C в Simulink, который вы хотите изменить. Чтобы вызвать одну функцию C из модели Simulink, используйте блок C Caller. Чтобы интегрировать динамические системы, которые имеют непрерывные состояния или изменения состояния, используйте блок S-Function.

Примечание

C99 является стандартной версией языка C, поддержанного для пользовательского интегрирования кода С в Simulink.

Следующие примеры используют блоки C Function, чтобы вычислить сумму и среднее значение входных параметров.

Запишите внешние исходные файлы

Начните путем создания внешних исходных файлов.

  1. Создайте заголовочный файл под названием 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);

  2. В той же папке создайте новый файл, 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;
    }

Введите внешний код в Simulink

  1. Создайте новую, пустую модель и добавьте блок C Function. Блок C Function находится в библиотеке User-Defined Functions Браузера Библиотеки.

  2. Дважды кликните блок C Function, чтобы открыть диалоговое окно блока. Щелкните, чтобы открыть диалоговое окно Configuration Parameters. В панели Simulation Target задайте свой заголовочный файл под Header file.

    Совет

    После того, как вы ввели информацию для Source files на следующем шаге, можно нажать Auto-fill from Source files, чтобы заполнить имя заголовочного файла автоматически, с помощью информации, содержавшейся в исходных файлах.

  3. Задайте исходный файл под Additional build information> Source files. Чтобы проверить, что ваш пользовательский код может быть проанализирован и создан успешно, нажмите Validate.

    Примечание

    Чтобы использовать блок C Function в Для Каждой подсистемы или со временем непрерывной выборки или оптимизировать использование блока в условном входном выполнении ветви, все функции пользовательского кода, вызванные блоком, должны быть детерминированы, то есть, всегда производя те же выходные параметры для тех же входных параметров. Идентифицируйте, какие функции пользовательского кода детерминированы при помощи Deterministic functions и параметров Specify by function в панели Simulation target. Если блок ссылается на какие-либо глобальные переменные пользовательского кода, то Deterministic functions должен установить на All для блока, который будет использоваться в Для Каждой подсистемы в условном входном выполнении ветви, или со временем непрерывной выборки.

    Для примера, показывающего блок C Function в Для Каждой подсистемы, смотрите блок C Function Использования В Для Каждой Подсистемы.

  4. В панели Output Code диалогового окна параметров блоков C Function запишите код, который блок выполняет в процессе моделирования. В этом примере внешняя функция C вычисляет сумму. В панели Output Code запишите код, который вызывает data_array.c функция, чтобы вычислить сумму, затем вычисляет среднее значение.

    /* declare the struct dataArr */
    DataArray dataArr;
    /* store the length and data coming in from the input port */
    dataArr.pData = &data[0];
    dataArr.length = length;
    
    /* call the function from the external code to calculate sum */
    sum = data_sum(dataArr);
    
    /* calculate the mean */
    mean = sum / length;

    Можно задать код, который запускается в начале симуляции и в конце симуляции в панелях Terminate Code и Start Code.

  5. Используйте таблицу Symbols, чтобы задать символы, используемые во внешнем коде С. Добавьте или удалите символ с помощью кнопок Add и Delete. Задайте все символы, используемые в Output Code, Start Code и панелях Terminate Code, чтобы гарантировать тот, порты отображаются правильно.

    В таблице Symbols задайте следующее:

    • Имя Имя символа в исходном коде.

    • Осциллограф Осциллограф символов и порядка, в котором они появляются. Можно изменить осциллограф символа в любое время.

      • Input — Вводимый символ с блоком C Function.

      • Output — Выведите символ с блоком C Function.

      • InputOutput — Задайте символ как оба ввода и вывода с блоком C Function.

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

        • InputOutput символ не может использоваться в Start и Terminate код.

        • InputOutput порт не поддерживает void* тип данных.

        • InputOutput порт не поддерживает size() выражения.

      • Persistent — Задайте символ как персистентные данные.

        Можно задать пустой указатель с помощью Persistent определите объем в блоке C Function. Пустой указатель является указателем, который может сохранить любой тип данных, которые вы создали или выделили.

      • Constant — Задайте символ как постоянный размер значения использования или числовые выражения.

      • Parameter — Задайте символ как параметр. Название параметра задано Label символа.

    • Метка Метка символа. Для символов с их набором осциллографа к Input или Output, эта метка появляется как имя порта на блоке. Для символов с их набором осциллографа к Parameter, эта метка является меткой, которая появляется на маске параметров блоков. Вы не можете задать метку для Persistent символы. Если осциллографом является Constant, метка является константным выражением.

    • Ввод Тип данных символа. Выберите тип данных из выпадающего списка или задайте пользовательский тип данных.

      Использовать пользовательский тип, такой как Simulink.Bus, Перечисление Simulink или Simulink.AliasType это не имеет внешнего определения заголовка сопоставленным с блоком C Function, установите тип правильно на таблице Symbol.

    • Размер Размер данных о символе. Блок C Function поддерживает только скаляры и векторы. Матрицы и массивы более высокой размерности не поддерживаются. Можно использовать выражение размера, чтобы задать размер выхода. Используйте -1 наследовать размер.

    • Порт Для символов ввода и вывода, Port указывает на индекс порта на блоке данных о символе. Для символов параметра, Port указывает на порядок, что символ появляется в маске параметров блоков.

    Закройте диалоговое окно параметров блоков. После заполнения данных в таблице блок C Function теперь имеет один входной порт и два выходных порта с метками, заданными в таблице.

  6. Добавьте блок Constant в холст Simulink, который будет входом с блоком C Function. В блоке Constant создайте случайный массив строк с 100 элементами. Чтобы отобразить результаты, присоедините блоки отображения к выходным параметрам блока C Function.

Вызовите библиотечные функции C от блока C Function

Можно вызвать это подмножество Математических Библиотечных функций C от блока C Function:

absacosasinatanatan2ceil
coscoshexpfabsfloorfmod
labsldexploglog10powsin
sinhsqrttantanh  

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

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

Вызовите abs, fabs, и labs Функции

Интерпретация abs, fabs, и labs функции в блоке C Function идут вне стандарта C версия, чтобы включать целочисленные и аргументы с плавающей точкой:

  • Если x целое число, стандарт C функциональный abs применяется к x, или abs(x).

  • Если x двойное, стандарт C функциональный labs применяется к x, или labs(x).

  • Если x сингл, стандарт C функциональный fabs применяется к x, или fabs(x).

Заменяющая библиотека кода (CRL) на основе типа

Вызов функции должен вызвать правильный 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 or C++, у вас есть опция, чтобы запустить пользовательский код в отдельном процессе за пределами MATLAB®. Эта опция может быть полезной при отладке пользовательского кода. Путем выполнения в отдельном процессе проблемы с пользовательским кодом не заставляют MATLAB отказывать, и можно более легко отладить и разрешить такие проблемы. Проблемы могли возникнуть из-за непредвиденных исключительных ситуаций в пользовательском коде или ошибок в интерфейсе между Simulink и пользовательском коде. Для получения дополнительной информации смотрите, Симулируют Пользовательский код в Отдельном Процессе.

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

Функции

Объекты

Блоки