Импортируйте вызовы внешнего кода в сгенерированный код с Legacy Code Tool

Legacy Code Tool и генерация кода

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

Примечание

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

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

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

  • Сгенерируйте Блок s-function маскированный, который сконфигурирован, чтобы вызвать существующий внешний код.

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

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

Для получения дополнительной информации смотрите, Интегрируют Функции C Используя Legacy Code Tool.

Сгенерируйте встроенные 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 поле структуры Legacy Code Tool задает несколько заголовочных файлов

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

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

  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 поле структуры Legacy Code Tool задает несколько заголовочных файлов

Обратитесь к зависимостям от файлов в других местах

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

Сгенерировать 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 Tool, вы вызываете legacy_code с 'sfcn_makecfg_generate' однажды.

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

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

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

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

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

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

  • Файл блока TLC

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

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

Когда вы используете эти развернутые файлы:

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

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

Интегрируйте внешние объекты C++

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

  • Измените определение класса для adder в новом файле adder_cpp.hpp. Добавьте три новых макросов, которые динамически выделяют новый adder возразите, вызовите метод add_one(), и освободите выделенную память. Каждый макрос берет указатель на adder объект. Поскольку каждая функция, вызванная Legacy Code Tool, должна иметь подобную 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() и обеспечивает определенный adder S-function объект указателя.

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

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

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

Похожие темы