Можно использовать 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®.
Если структура данных 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)';