Можно использовать Simulink® Legacy Code Tool, чтобы сгенерировать полностью встроенные S-функции MEX C для наследия или пользовательского кода. S-функции оптимизированы для встроенных компонентов, таких как драйверы устройств и интерполяционные таблицы, и они вызывают существующий C или функции C++.
Примечание
Legacy Code Tool может взаимодействовать через интерфейс с функциями C++, но не объектами C++. Чтобы работать вокруг этой проблемы так, чтобы инструмент мог взаимодействовать через интерфейс с объектами C++, смотрите Ограничения Legacy Code Tool.
Можно использовать инструмент для:
Если вы хотите включать эти типы 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-функцию, делают любое из следующего:
Сгенерируйте один .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
поле к 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. Например:
def = legacy_code('initialize');
В структуре данных, установленной значение Options.singleCPPMexFile
поле к true
. Например:
def.Options.singleCPPMexFile = true;
Проверять установку, введите:
def.Options.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-функции, которые вы генерируете с Legacy Code Tool так, чтобы другие люди могли использовать их. Чтобы развернуть S-функцию для симуляции и генерации кода, совместно используйте следующие файлы:
Регистрационный файл
Скомпилированный динамически загружаемый исполняемый файл
Файл блока TLC
sFunction
_makecfg.m
или rtwmakecfg.m
файл
Заголовок, источник, и включают файлы, от которых зависит сгенерированная S-функция
Когда вы используете эти развернутые файлы:
Перед использованием развернутых файлов в модели Simulink добавьте папку, которая содержит S-файлы-функции к MATLAB® path.
Если структура данных Legacy Code Tool регистрирует требуемые файлы как абсолютные пути и местоположение изменений файлов, регенерируйте sFunction
_makecfg.m
или rtwmakecfg.m
файл.
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)';