exponenta event banner

Вызов и интеграция внешних алгоритмов C в Simulink

Внешний код 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 для вычисления суммы и среднего значения входных данных.

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

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

  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. Блок функций C находится в библиотеке пользовательских функций браузера библиотеки.

  2. Дважды щелкните блок C Function, чтобы открыть диалоговое окно блока. Нажмите для открытия диалогового окна «Параметры конфигурации». На панели Цель моделирования определите файл заголовка в разделе Вставить пользовательский код C в сгенерированном: > Файл заголовка.

  3. Определите исходный файл в разделе Дополнительные сведения о построении > Исходные файлы.

    Примечание

    Чтобы использовать блок C Function в подсистеме For Each или с непрерывным временем выборки, или для оптимизации использования блока при выполнении условной ветви ввода, все пользовательские функции кода, вызываемые блоком, должны быть детерминированными, то есть всегда создавать одни и те же выходы для одних и тех же входов. Определите, какие пользовательские функции кода являются детерминированными, используя функции Детерминированные (Deterministic) и Указать по параметрам функции (Specify by function parameters) на целевой панели Моделирование (Simulation). Если блок ссылается на какие-либо пользовательские глобальные переменные кода, то детерминированные функции должны иметь значение All для использования блока в подсистеме For Each, при выполнении условного входного ответвления или с непрерывным временем выборки.

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

    Нажмите кнопку ОК, чтобы закрыть окно Параметры конфигурации (Configuration Parameters).

  4. На панели «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).

  5. Таблица Символы (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 теперь имеет один входной порт и два выходных порта с метками, указанными в таблице.

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

Функции библиотеки вызовов C из функционального блока C

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

absacosasinatanatan2ceil
coscoshexpfabsfloorfmod
labsldexploglog10powsin
sinhsqrttantanh  

При вызове этих функций применяется двойная точность, если все входные аргументы явно не являются одной точностью. При несовпадении типов приведение входных аргументов к ожидаемому типу заменяет исходные аргументы. Например, при вызове 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 не указан, вызов функции должен вызывать библиотеку, зависящую от типа. 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 и пользовательским кодом. Дополнительные сведения см. в разделе Моделирование пользовательского кода в отдельном процессе.

См. также

Функции

Объекты

Блоки