exponenta event banner

Импорт вызовов внешнего кода в сгенерированный код с помощью инструмента устаревшего кода

Устаревший инструмент и создание кода

Для создания полностью встроенных C MEX S-функций для устаревшего или пользовательского кода можно использовать инструмент кода Simulink ® Legacy Code Tool. S-функции оптимизированы для встраиваемых компонентов, таких как драйверы устройств и таблицы поиска, и они вызывают существующие функции C или C++.

Примечание

Legacy Code Tool может взаимодействовать с функциями C++, но не с объектами C++. Чтобы обойти эту проблему, чтобы инструмент мог взаимодействовать с объектами C++, см. раздел Ограничения устаревших инструментов кода.

Инструмент можно использовать для:

  • Скомпилировать и построить сгенерированную S-функцию для моделирования.

  • Создайте маскированный блок S-Function, который сконфигурирован для вызова существующего внешнего кода.

Если требуется включить эти типы S-функций в модели, для которых предполагается создать код, используйте инструмент для создания файла блока TLC. Файл блока TLC указывает, как созданный код для модели вызывает существующую функцию C или C++.

Если S-функция зависит от файлов в папках, отличных от папки, содержащей динамически загружаемый исполняемый файл S-функции, используйте инструмент для создания sFunction_makecfg.m или rtwmakecfg.m файл для S-функции. При создании файла эти зависимости сохраняются при построении модели, включающей S-функцию. Например, для некоторых приложений, таких как пользовательские конечные объекты, может потребоваться найти файлы в определенном расположении. Процесс построения ищет sFunction_makecfg.m или rtwmakecfg.m в той же папке, что и динамически загружаемый исполняемый файл S-функции, и вызывает функцию в файле.

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

Создание встроенных файлов S-функций для создания кода

В зависимости от требований к созданию кода приложения для создания кода модели, использующей S-функцию, выполните одно из следующих действий:

  • Создать один .cpp для встроенной S-функции. В структуре данных Legacy Code Tool задайте значение Options.singleCPPMexFile поле в true перед созданием исходного файла S-функции из существующей функции C. Например:

    def.Options.singleCPPMexFile = true;
    legacy_code('sfcn_cmex_generate', def);

  • Создайте исходный файл и файл блока TLC для встроенной S-функции. Например:

    def.Options.singleCPPMexFile = false;
    legacy_code('sfcn_cmex_generate', def);
    legacy_code('sfcn_tlc_generate', def);

Ограничения singleCPPMexFile

Вы не можете установить singleCPPMexFile поле в true если

  • Options.language='C++'

  • Один из следующих объектов Simulink используется с IsAlias свойство имеет значение true:

    • Simulink.Bus

    • Simulink.AliasType

    • Simulink.NumericType

  • Спецификация функции Legacy Code Tool включает void* или void** для представления скалярных рабочих данных для аргумента состояния

  • HeaderFiles поле в структуре «Устаревший инструмент кода» определяет несколько заголовочных файлов

Применить параметры стиля кода к устаревшим функциям

Чтобы применить параметры конфигурации модели для стиля кода к устаревшей функции:

  1. Инициализируйте структуру данных Legacy Code Tool. Например:

    def = legacy_code('initialize');
    
  2. В структуре данных задайте значение Options.singleCPPMexFile поле в true. Например:

    def.Options.singleCPPMexFile = true;

Для проверки настройки введите:

def.Options.singleCPPMexFile

Ограничения singleCPPMexFile

Вы не можете установить singleCPPMexFile поле в true если

  • Options.language='C++'

  • Один из следующих объектов Simulink используется с IsAlias свойство имеет значение true:

    • Simulink.Bus

    • Simulink.AliasType

    • Simulink.NumericType

  • Спецификация функции Legacy Code Tool включает void* или void** для представления скалярных рабочих данных для аргумента состояния

  • HeaderFiles поле в структуре «Устаревший инструмент кода» определяет несколько заголовочных файлов

Адресация зависимостей от файлов в различных расположениях

По умолчанию инструмент кода предыдущей версии предполагает, что файлы, от которых зависит S-функция, находятся в той же папке, что и динамически загружаемый исполняемый файл для S-функции. Если функция S зависит от файлов, которые находятся в другом месте, и вы используете процесс создания файла шаблона, создайте sFunction_makecfg.m или rtwmakecfg.m файл для S-функции. Например, этот файл может быть создан, если структура данных прежнего инструмента кода определяет ресурсы компиляции как имена путей.

Для создания sFunction_makecfg.m или rtwmakecfg.m файл, вызовите legacy_code функция с 'sfcn_makecfg_generate' или 'rtwmakecfg_generate' в качестве первого аргумента и имя структуры данных Legacy Code Tool в качестве второго аргумента. Например:

legacy_code('sfcn_makecfg_generate', lct_spec);

Если вы используете несколько файлов регистрации в одной папке и генерируете S-функцию для каждого файла с одним вызовом legacy_code, вызов legacy_code который определяет 'sfcn_makecfg_generate' или 'rtwmakecfg_generate' должен быть общим для всех файлов регистрации. Дополнительные сведения см. в разделе Обработка нескольких файлов регистрации.

Например, при определении defs в качестве массива устаревших структур инструментов кода вызывается legacy_code с 'sfcn_makecfg_generate' один раз.

defs = [defs1(:);defs2(:);defs3(:)];
legacy_code('sfcn_makecfg_generate', defs);

Дополнительные сведения см. в разделе Поддержка сборки S-функций.

Развертывание S-функций для моделирования и создания кода

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

  • Регистрационный файл

  • Компилированный динамически загружаемый исполняемый файл

  • Файл блока TLC

  • sFunction_makecfg.m или rtwmakecfg.m файл

  • Заголовок, источник и включаемые файлы, от которых зависит сгенерированная S-функция

При использовании этих развернутых файлов:

  • Перед использованием развернутых файлов в модели Simulink добавьте папку, содержащую файлы S-функций, в путь MATLAB ®.

  • Если структура данных прежнего инструмента кода регистрирует требуемые файлы как абсолютные пути, и местоположение файлов изменяется, выполните регенерацию sFunction_makecfg.m или rtwmakecfg.m файл.

Интеграция внешних объектов C++

Legacy Code Tool может взаимодействовать с функциями C++, но не с объектами C++. Используя предыдущий пример в качестве отправной точки, вот пример того, как можно обойти это ограничение.

  • Изменение определения класса для adder в новом файле adder_cpp.hpp. Добавить три новых макроса, которые динамически распределяют новый adder объект, вызовите метод add_one()и освободить выделенную память. Каждый макрос принимает указатель на adder объект. Поскольку каждая функция, вызываемая средством устаревшего кода, должна иметь C-образную подпись, указатель кэшируется и передается как void*. Затем необходимо явно привести к adder* в макросе. Новое определение класса для adder:

    #ifndef _ADDER_CPP_
    #define _ADDER_CPP_
    
    class adder {
    private:
    	int int_state;
    public:
    	adder(): int_state(0) {};
    	int add_one(int increment);
    	int get_val() {return int_state;};
    };
    
    // Method wrappers implemented as macros
    #define createAdder(work1) \
        *(work1) = new adder
    
    #define deleteAdder(work1) \
        delete(static_cast<adder*>(*(work1)))
    
    #define adderOutput(work1, u1) \
        (static_cast<adder*> ((work1)))->add_one(u1)
    
    #endif /* _ADDER_CPP_ */
  • Обновление adder_cpp.cpp. При изменении класса вместо одного глобального экземпляра каждая сгенерированная S-функция управляет своей собственной adder объект.

    #include "adder_cpp.hpp"
    
    int adder::add_one(int increment)
    {
    	int_state += increment;
        return int_state;
    }
  • Обновление rtwdemo_sfun_adder_cpp.cpp со следующими изменениями:

    • StartFcnSpec вызывает макрос, который выделяет новый adder объект и кэширует указатель.

      def.StartFcnSpec  = 'createAdder(void **work1)';
      
    • OutputFcnSpec вызывает макрос, вызывающий метод add_one() и обеспечивает специфическую функцию S adder объект указателя.

      def.OutputFcnSpec = 'int32 y1 = adderOutput(void *work1, int32 u1)';
    • TerminateFcnSpec вызывает макрос, освобождающий память.

      def.TerminateFcnSpec = 'deleteAdder(void **work1)';

См. также

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