Можно интегрировать существующий C (или C++) функции, такие как драйверы устройств, интерполяционные таблицы, и общие функции и интерфейсы, в модели Simulink® при помощи Legacy Code Tool. Используя спецификации, которые вы предоставляете как код MATLAB®, инструмент преобразовывает существующие функции в S-функции MEX C, которые можно включать в модели Simulink. Если вы используете Simulink Coder™, чтобы сгенерировать код, Legacy Code Tool может вставить соответствующий вызов вашей функции C в сгенерированный код. Для получения дополнительной информации смотрите Вызовы Импорта Внешнего Кода в Сгенерированный код с Legacy Code Tool (Simulink Coder).
По сравнению с использованием Разработчика S-функции или записью S-функции, Legacy Code Tool легче использовать и генерирует оптимизированный код (не генерирует код обертки), часто требуемый встраиваемыми системами. Однако рассмотрите альтернативные подходы для гибридной системы, такие как система, которая включает объект и контроллер или компонент системы, написанный в языке кроме C или C++. Альтернативные подходы более гибки в этом, они поддерживают больше функций и языков программирования.
Взаимодействовать с Legacy Code Tool, вами
Используйте структуру данных Legacy Code Tool, чтобы задать
Имя для S-функции
Спецификации для существующих функций C
Файлы и пути требуются для компиляции
Опции для сгенерированной S-функции
Используйте функцию legacy_code
для
Инициализируйте структуру данных Legacy Code Tool для данной функции C
Сгенерируйте S-функцию для использования во время симуляции
Скомпилируйте и соедините сгенерированную S-функцию в динамически загружаемый исполняемый файл
Сгенерируйте Блок s-function маскированный для вызова сгенерированной S-функции
Сгенерируйте файл блока TLC и, при необходимости, _makecfg.m
sFunction
или файл rtwmakecfg.m
для генерации кода (требуемая лицензия на продукты Simulink Coder)
Прежде чем можно будет использовать legacy_code
, гарантировать, что компилятор C настраивается для установки MATLAB.
Следующая схема иллюстрирует общую процедуру для использования Legacy Code Tool. Объединяйтесь Функции C в Модели Simulink с Legacy Code Tool обеспечивает пример, который использует Legacy Code Tool, чтобы преобразовать существующую функцию C в S-функцию MEX C.
Если у вас есть лицензия на продукты Simulink Coder, смотрите Вызовы Импорта Внешнего Кода в Сгенерированный код с Legacy Code Tool (Simulink Coder) для получения информации об использовании Legacy Code Tool для генерации кода.
Этот пример демонстрирует, как интегрировать существующую функцию C в модель Simulink с помощью Legacy Code Tool.
Предположим, что у вас есть функция C, которая выводит значение ее входа с плавающей точкой, умноженного на два. Функция задана в исходном файле под названием doubleIt.c
, и его объявление существует в заголовочном файле под названием doubleIt.h
.
Инициализируйте struct MATLAB def
с полями, которые представляют свойства Legacy Code Tool с помощью функции legacy_code
.
def = legacy_code('initialize')
Структура данных Legacy Code Tool под названием def
отображает свои поля в окне команды MATLAB как показано здесь:
def = SFunctionName: '' InitializeConditionsFcnSpec: '' OutputFcnSpec: '' StartFcnSpec: '' TerminateFcnSpec: '' HeaderFiles: {} SourceFiles: {} HostLibFiles: {} TargetLibFiles: {} IncPaths: {} SrcPaths: {} LibPaths: {} SampleTime: 'inherited' Options: [1x1 struct]
Задайте соответствующие значения для полей в структуре данных Legacy Code Tool, чтобы идентифицировать свойства существующей функции C. Например, задайте источник функции C и имена файлов заголовка путем ввода следующих команд в подсказке команды MATLAB:
def.SourceFiles = {'doubleIt.c'}; def.HeaderFiles = {'doubleIt.h'};
Необходимо также указать информацию о S-функции, которую Legacy Code Tool производит из кода С. Например, задайте имя для S-функции и ее объявления выходной функции путем ввода:
def.SFunctionName = 'ex_sfun_doubleit'; def.OutputFcnSpec = 'double y1 = doubleIt(double u1)';
Для получения информации о различных полях структуры данных смотрите страницу с описанием legacy_code
.
Сгенерируйте исходный файл S-функции от существующей функции C при помощи функции legacy_code
. В подсказке команды MATLAB введите:
legacy_code('sfcn_cmex_generate', def);
Legacy Code Tool использует информацию, указанную в def
, чтобы создать исходный файл S-функции под названием ex_sfun_doubleit.c
в текущей папке MATLAB.
Скомпилируйте и соедините исходный файл S-функции в динамически загружаемый исполняемый файл для Simulink с помощью thelegacy_code
функцию. В подсказке команды MATLAB введите:
legacy_code('compile', def);
Следующие сообщения появляются в окне команды MATLAB:
### Start Compiling ex_sfun_doubleit mex('ex_sfun_doubleit.c', 'd:\work\lct_demos\doubleIt.c', '-Id:\work\lct\lct_demos') ### Finish Compiling ex_sfun_doubleit ### Exit
В 32-битной системе Microsoft® Windows® получившийся исполняемый файл S-функции называют ex_sfun_doubleit.mexw32
.
Вставьте Блок s-function маскированный в модель Simulink.
legacy_code('slblock_generate', def);
Legacy Code Tool конфигурирует блок, чтобы использовать S-функцию MEX C, созданную на предыдущем шаге. Кроме того, инструмент маскирует блок, таким образом, что это отображает значение своего свойства OutputFcnSpec
(см. описание функции legacy_code
).
Добавьте блок Sine Wave амплитуды 1 к входу Блока s-function C-MEX и блока Scope к выводу.
Запустите симуляцию. Блок s-function C-MEX возвращает значение своего входа с плавающей точкой, умноженного на два. Это ведет себя как функция C doubleIt
.
Этот пример показывает, как использовать Legacy Code Tool, чтобы интегрировать функцию C, аргументы которой являются указателями на структуры.
В Simulink® создайте объект Simulink.Bus
представлять тип структуры. Используйте сигналы шины в модели, чтобы представлять структурированные сигналы и состояния. Создайте структуры MATLAB в рабочей области или в диалоговом окне параметров блоков, чтобы представлять структуры параметра.
Для основной информации о сигналах шины смотрите Шины. Для основной информации о структурах параметра смотрите, Организуют Связанные Определения Параметров блоков в Структурах. Чтобы создать объекты шины, смотрите, Создают Объекты Шины с Редактором Шины.
Исследуйте внешний код
Скопируйте этот пользовательский исходный код в файл с именем ex_mySrc_LCT.c
в вашей текущей папке.
#include "ex_myTypes_LCT.h" void myFcn(sigStructType *in, paramStructType *params, sigStructType *out) { out->sig1 = in->sig1 * params->param1; out->sig2 = in->sig2 * params->param2 + params->param3; }
Аргументы функционального myFcn
являются указателями на структуры. Функция принимает аргумент входного сигнала, аргумент параметра и аргумент выходного сигнала.
Скопируйте этот пользовательский код заголовка в файл с именем ex_myTypes_LCT.h
в вашей текущей папке.
#ifndef _MY_TYPES_H_ #define _MY_TYPES_H_ typedef struct { double sig1; double sig2; } sigStructType; typedef struct { double param1; double param2; double param3; } paramStructType; #endif
Файл задает сигнал, и структура параметра вводит тот myFcn
использование.
Создайте объекты шины представлять типы структуры в Simulink
В командной строке используйте функциональный Simulink.importExternalCTypes
, чтобы сгенерировать объекты шины в базовом рабочем пространстве.
Simulink.importExternalCTypes('ex_myTypes_LCT.h');
Объекты шины соответствуют типам struct
, которые задает ex_myTypes_LCT.h
.
Создайте блок, чтобы выполнить внешний код
Создайте переменную структуры, def
, чтобы сохранить спецификации для S-функции, которая вызывает внешний код. Используйте функциональный legacy_code
, чтобы создать структуру и установить значения по умолчанию.
def = legacy_code('initialize');
Определите имя S-функции к sfun_ex_mySrc_LCT
.
def.SFunctionName = 'sfun_ex_mySrc_LCT';
Идентифицируйте внешний источник и заголовочные файлы их именами файлов.
def.SourceFiles = {'ex_mySrc_LCT.c'}; def.HeaderFiles = {'ex_myTypes_LCT.h'};
Задайте прототип выходной функции, которая модель вызывает каждый шаг симуляции путем копирования прототипа внешнего функционального myFcn
. Определите имена аргументов к u1
, p1
и y1
, чтобы представлять входной параметр, аргумент параметра и выходной аргумент. Используйте синтаксис [1]
, чтобы указать, что каждый аргумент является указателем.
def.OutputFcnSpec = ['void myFcn(sigStructType u1[1], ',... 'paramStructType p1[1], sigStructType y1[1])'];
Используйте функциональный legacy_code
, чтобы создать S-функцию и соответствующий исполняемый файл MEX C от спецификации, def
. Задайте опцию 'generate_for_sim'
, чтобы подготовить S-функцию к нормальным и ускоренным симуляциям.
legacy_code('generate_for_sim',def);
### Start Compiling sfun_ex_mySrc_LCT mex('-I/tmp/BR2019ad_1035872_198992/publish_examples6/tp753f13fd/ex12763634', '-c', '-outdir', '/tmp/BR2019ad_1035872_198992/publish_examples6/tpcd9fe5a2_97e6_4978_a7cb_ee76833ef802', '/tmp/BR2019ad_1035872_198992/publish_examples6/tp753f13fd/ex12763634/ex_mySrc_LCT.c') Building with 'gcc'. MEX completed successfully. mex('sfun_ex_mySrc_LCT.c', '-I/tmp/BR2019ad_1035872_198992/publish_examples6/tp753f13fd/ex12763634', '/tmp/BR2019ad_1035872_198992/publish_examples6/tpcd9fe5a2_97e6_4978_a7cb_ee76833ef802/ex_mySrc_LCT.o') Building with 'gcc'. /tmp/BR2019ad_1035872_198992/publish_examples6/tp753f13fd/ex12763634/sfun_ex_mySrc_LCT.c: In function ‘mdlOutputs’: /tmp/BR2019ad_1035872_198992/publish_examples6/tp753f13fd/ex12763634/sfun_ex_mySrc_LCT.c:417:9: warning: implicit declaration of function ‘myFcn’ [-Wimplicit-function-declaration] myFcn(__u1BUS, __p1BUS, __y1BUS); ^~~~~ MEX completed successfully. ### Finish Compiling sfun_ex_mySrc_LCT ### Exit
Создайте Блок s-function маскированный, который вызывает S-функцию во время симуляции.
legacy_code('slblock_generate', def);
Блок появляется в новой модели.
Чтобы использовать Блок s-function в вашей модели, создайте сигнал шины типа sigStructType
, чтобы использовать в качестве входа блока. Блок вывод является также сигналом шины. Маска блока принимает параметр, P1. Чтобы установить значение параметра, используйте структуру MATLAB, поля которой соответствуют, те из структуры вводят paramStructType
.
Проверьте подписание внешнего кода
Создайте модель тестовой обвязки, которая проверяет подписание внешнего кода во время симуляции.
Для примера просмотрите модель ex_lct_struct
.
open_system('ex_lct_struct')
В диалоговом окне блока Constant параметр Постоянного значения устанавливается на структуру, поля которой соответствуют, те из структуры вводят sigStructType
. На вкладке Signal Attributes тип Выходных данных установлен в объект sigStructType
шины.
Блок s-function вызывает S-функцию sfun_ex_mySrc_LCT
, который вы создали. Вывод блока вводит блок Селектора Шины, который извлекает элементы сигнала sig1
и sig2
.
Блок s-function принимает параметр через диалоговое окно маски. Создайте структуру MATLAB structParam
, чтобы использовать в качестве значения параметра.
structParam = struct; structParam.param1 = 15; structParam.param2 = 20; structParam.param3 = 5;
Опционально, используйте объект Simulink.Parameter
содержать структуру. Если вы используете объект параметра, можно установить тип данных структуры при помощи объекта paramStructType
шины.
structParam = Simulink.Parameter(structParam);
structParam.DataType = 'Bus: paramStructType';
В диалоговом окне маски, набор P1 к structParam
.
set_param('ex_lct_struct/sfun_ex_mySrc_LCT','SParameter1','structParam')
Моделируйте модель. Блоки Scope показывают, что Блок s-function вызывает внешний функциональный myFcn
.
open_system('ex_lct_struct/Scope') open_system('ex_lct_struct/Scope1') sim('ex_lct_struct')
ans = Simulink.SimulationOutput: tout: [51x1 double] SimulationMetadata: [1x1 Simulink.SimulationMetadata] ErrorMessage: [0x0 char]
Первый шаг к использованию Legacy Code Tool должен указать одну или несколько структур MATLAB с полями, которые представляют свойства существующего кода С и сгенерированной S-функции. Процесс регистрации гибок. Можно принять решение настроить ресурсы и инициировать регистрацию во множестве путей, включая
Размещение всего необходимого заголовка и исходных файлов в текущей рабочей папке или в иерархической структуре папок
Генерация и размещение одной или нескольких S-функций в текущей рабочей папке
Наличие одного или нескольких регистрационных файлов в той же папке
Указывать структуру данных Legacy Code Tool:
Используйте функцию legacy_code
, задавая 'initialize'
в качестве первого аргумента.
lct_spec = legacy_code('initialize')
Структура данных Legacy Code Tool под названием lct_spec
отображает свои поля в окне команды MATLAB как показано ниже:
lct_spec = SFunctionName: '' InitializeConditionsFcnSpec: '' OutputFcnSpec: '' StartFcnSpec: '' TerminateFcnSpec: '' HeaderFiles: {} SourceFiles: {} HostLibFiles: {} TargetLibFiles: {} IncPaths: {} SrcPaths: {} LibPaths: {} SampleTime: 'inherited' Options: [1x1 struct]
Задайте значения для полей структуры данных (свойства), которые применяются к вашей существующей функции C и S-функции, которую вы намереваетесь сгенерировать. Минимально, необходимо задать
Исходные и заголовочные файлы для существующей функции C (SourceFiles
и HeaderFiles
)
Имя для S-функции (SFunctionName
)
По крайней мере одна функциональная спецификация для S-функции (InitializeConditionsFcnSpec
, OutputFcnSpec
, StartFcnSpec
, TerminateFcnSpec
)
Для полного списка и описаний полей в структуре, смотрите страницу ссылки на функцию legacy_code
.
Если вы задаете поля, которые задают ресурсы компиляции, и вы задаете относительные пути, Legacy Code Tool ищет ресурсы относительно следующих директорий в следующем порядке:
Текущая рабочая папка
Папка S-функции C-MEX, если отличающийся, чем текущая рабочая папка
Директории вы задаете
IncPaths
для заголовочных файлов
SrcPaths
для исходных файлов
LibPaths
для цели и библиотек хоста
Директории на пути поиска файлов MATLAB, исключая директории тулбокса
InitializeConditionsFcnSpec
, OutputFcnSpec
, StartFcnSpec
и
поля TerminateFcnSpec
, заданные в структуре данных Legacy Code Tool (см. описание функции legacy_code
), требуют значений вектора символов, которые придерживаются определенного формата синтаксиса. Необходимый формат синтаксиса позволяет Legacy Code Tool сопоставить возвращаемое значение и аргументы существующей функции C к возвращаемому значению, входным параметрам, выходным параметрам, параметрам, и работать векторы S-функции, которую генерирует инструмент.
Общий синтаксис
return-spec = function-name(argument-spec)
Например, следующий вектор символов задает функцию с именем doubleIt
со спецификацией возврата double y1
и спецификация входного параметра double u1
.
def.OutputFcnSpec = 'double y1 = doubleIt(double u1)';
Для большего количества детали об объявлении функциональных спецификаций смотрите
Спецификация возврата задает имя типа данных и имя переменной для возвращаемого значения существующей функции C.
return-type return-variable
| Тип данных перечислен в Поддерживаемых Типах данных. |
| Лексема формы y1 , y2 , ... , y n, где n является общим количеством выходных аргументов. |
Если функция не возвращает значение, можно не использовать спецификацию возврата или задать его как void
.
Следующая таблица показывает допустимый функциональный синтаксис спецификации для целочисленного возвращаемого значения. Используйте таблицу, чтобы идентифицировать синтаксис, который необходимо использовать для прототипа функции C.
Возвратите тип | C прототип функции | Спецификация функции Legacy Code Tool |
---|---|---|
Никакое возвращаемое значение | void myfunction(...) | void myfunction(...) |
Скалярное значение | int = myfunction(...) | int16 y1 = myfunction(...) |
Имя функции, которое вы задаете, должно совпасть с вашим существующим именем функции C.
Например, рассмотрите следующего прототипа функции C:
float doubleIt(float inVal);
В этом случае именем функции в спецификации функции Legacy Code Tool должен быть doubleIt
.
Вы не должны задавать имя макроса C. Если вы должны, установить поле Options.isMacro
на true
в случае, если сворачивание выражения включено.
Спецификация аргумента задает один или несколько тип данных и маркерные пары, которые представляют вход, выводят, параметр, и работают аргументы вектора существующей функции C. Входной параметр функции и карта выходных аргументов, чтобы блокировать порты ввода и вывода и параметры сопоставляют с параметрами рабочей области.
argument-type argument-token
| Тип данных перечислен в Поддерживаемых Типах данных. |
| Лексема одной из следующих форм:
|
Если функция не имеет никаких аргументов, можно не использовать спецификацию аргумента или задать его как void
.
Рассмотрите следующего прототипа функции C:
float powerIt(float inVal, int exponent);
Чтобы сгенерировать S-функцию, которая вызывает предыдущую функцию на каждом временном шаге, устанавливает поле OutputFcnSpec
структуры данных Legacy Code Tool на следующее:
'single y1 = powerIt(single u1, int16 p1)'
Используя эту функциональную спецификацию, Legacy Code Tool сопоставляет следующую информацию.
Возвращаемое значение или аргумент | из типа C | К лексеме | из типа данных |
---|---|---|---|
Возвращаемое значение | float | y1 | single |
inVal | float | u1 | single |
exponent | int | p1 | int16 |
Если ваша функция требует Блока s-function Simulink с несколькими портами ввода и вывода, аргументами функции карты к входным портам с помощью исключительно пронумерованной лексемы u
. Для выходных портов используйте исключительно пронумерованную лексему y
. Эти лексемы описаны в предыдущей таблице спецификации аргумента. Например, рассмотрите следующего прототипа функции C:
void myfunc(double *y2, double u2, double u3, double u1, double *y1);
Вектор символов OutputFcnSpec
, сопоставляющий аргументы с портами ввода и вывода, выглядит подобным следующему:
'void myfunc(double y2[1], double u2, double u3, double u1, double y1[1])'
Получившийся Блок s-function включает три входных порта и два выходных порта. Первый вход сопоставляет с аргументом функции u1
, второй вход к u2
и третий вход к u3
. Для выходных портов аргумент функции, который y1[1]
сопоставляет с первым выводом и аргументом y2[1]
, сопоставляет со вторым выводом. Для другого примера отображения прототипа функции к нескольким портам ввода и вывода смотрите Используя Шины с Устаревшими Функциями, Имеющими Аргументы Структуры.
Следующая таблица показывает допустимый функциональный синтаксис спецификации для аргументов целого числа типа. Используйте таблицу, чтобы идентифицировать и затем адаптировать синтаксис, который необходимо использовать для прототипа функции C.
Тип аргумента | C прототип функции | Спецификация функции Legacy Code Tool |
---|---|---|
Входные параметры | ||
Никакие аргументы | function(void) | function(void) |
Скалярная передача значением | function(int in1) | function(int16 u1) |
Скалярная передача указателем | function(int *in1) | function(int16 u1[1]) |
Фиксированный вектор | function(int in1[10]) илиfunction(int *in1) | function(int16 u1[10]) |
Переменный вектор | function(int in1[]) илиfunction(int *in1) | function(int16 u1[]) |
Фиксированная матрица | function(int in1[15]) илиfunction(int in1[]) илиfunction(int *in1) | function(int16 u1[3][5]) |
Переменная матрица | function(int in1[]) илиfunction(int *in1) | function(int16 u1[][]) |
Выходные аргументы | ||
Скалярный указатель | function(int *y1) | function(int16 y1[1]) |
Фиксированный вектор | function(int y1[10]) илиfunction(int *y1) | function(int16 y1[10]) |
Фиксированная матрица | function(int y1[15]) илиfunction(int y1[]) илиfunction(int *y1) | function(int16 y1[3][5]) |
Аргументы параметра | ||
Скалярная передача значением | function(int p1) | function(int16 p1) |
Скалярная передача указателем | function(int *p1) | function(int16 p1[1]) |
Фиксированный вектор | function(int p1[10]) илиfunction(int *p1) | function(int16 p1[10]) |
Переменный вектор | function(int p1[]) илиfunction(int *p1) | function(int16 p1[]) |
Фиксированная матрица | function(int p1[15]) илиfunction(int p1[]) илиfunction(int *p1) | function(int16 p1[3][5]) |
Переменная матрица | function(int p1[]) илиfunction(int *p1) | function(int16 p1[][]) |
Аргументы вектора работы | ||
Скаляр передается значением | function(int work1) | function(int16 work1) |
Скалярный указатель | function(int *work1) function(void *work1) function(void **work1) | function(int16 work1[1]) void function(void *work1) void function(void **work1) |
Фиксированный вектор | function(int work1[10]) илиfunction(int *work1) | function(int16 work1[10]) |
Фиксированная матрица | function(int work1[15]) илиfunction(int work1[]) илиfunction(int *work1) | function(int16 work1[3][5]) |
Тип данных | Поддерживаемый для ввода и вывода? | Поддерживаемый для параметров? | Поддерживаемый для векторов работы? |
---|---|---|---|
Типы данных, Поддержанные Simulink (за исключением string ) | Да | Да | Да |
Simulink.Bus 1 | Да | Да | Да |
Массив Simulink.Bus 2 | Да | Нет | Да |
Simulink.NumericType 3 | Да | Да | Да |
Simulink.AliasType 1 | Да | Да | Да |
enum 1 | Да | Да | Да |
Фиксированный-point4 | Да | Да | Да |
Фи возражает | Нет данных | Да | Нет данных |
Комплекс numbers5 | Да | Да | Да |
1D массив | Да | Да | Да |
2D array6 | Да | Да | Да |
n-D array7 | Да | Да | Да |
пусто * | Нет | Нет | Да |
пусто ** | Нет | Нет | Да |
Необходимо предоставить заголовочный файл, который задает структуру шины, задает тип enum
или задает тип данных с тем же именем как псевдоним. Структура шины, объявленной в заголовочном файле, должна совпадать со структурой объекта шины (например, номер и порядок элементов, типов данных и ширин элементов, и так далее). Для примера смотрите sldemo_lct_bus
.
Чтобы сгенерировать объекты типа данных и классы перечисления, которые соответствуют пользовательским типам данных, которые задает ваш код С, используйте функцию Simulink.importExternalCTypes
.
Элемент шины может быть комплексным, но только с Simulink встроенные типы данных. Вложение массивов к любому уровню также поддержано.
Необходимо предоставить заголовочный файл, который задает тип данных, только если тип числовых данных является также псевдонимом.
Необходимо объявить данные как объект Simulink.NumericType
(незаданное масштабирование не поддержано). Для примеров смотрите sldemo_lct_fixpt_signals
и sldemo_lct_fixpt_params
.
Ограниченный, чтобы использовать с Simulink встроенные типы данных. Чтобы задать сложный тип данных, заключите встроенный тип данных в угловых скобках (<>) и предварительно ожидайте слово complex
(например, complex<double>
). Для примера смотрите sldemo_lct_cplxgain
.
MATLAB, Simulink и продукты Simulink Coder хранят данные о многомерном массиве в главном столбцом формате как вектор. Если ваш внешний функциональный код записан для главных строкой данных, используйте опцию S-функции convertNDArrayToRowMajor
в legacy_code
.
Для многомерного сигнала можно использовать функцию size
, чтобы определить число элементов в сигнале. Для примеров смотрите sldemo_lct_lut
и sldemo_lct_ndarray
.
Для получения дополнительной информации смотрите Типы данных, Поддержанные Simulink.
Спецификации для legacy_code
должны придерживаться следующих правил:
Если аргумент не является скаляром, необходимо передать аргумент ссылкой.
Нумерация входа, вывод, параметр, и работают, лексемы аргумента вектора должны запуститься в 1 и увеличиться монотонно.
Для данной структуры данных Legacy Code Tool, типа данных и размера входа, вывода, параметра, и работают, аргументы вектора должны быть тем же самым через функциональные спецификации для StartFcnSpec
, InitializeConditionsFcnSpec
, OutputFcnSpec
и TerminateFcnSpec
.
Можно задать размерности аргумента с выражениями, которые используют следующее:
Функции: numel
, size
Значения параметров
Операторы: +
, -
, *
и /
Целочисленные и литералы с плавающей точкой
Круглые скобки для группировки подвыражений
Например:
def.OutputFcnSpec= foo4(int8 p1[], int8 u1[], double y1[numel(u1)+2][numel(u1)+3], ... int32 (numel(p1)+numel(u1))*2+size(y1,2))';
Чтобы интегрировать функцию C использование Legacy Code Tool, функция должна придерживаться следующих правил:
Функция не должна изменять значение входных параметров. Если входной сигнал является переданным ссылкой аргументом к функции, функция не должна изменять данные, на которые указывает аргумент.
Возвращаемое значение функции не может быть указателем.
Функциональные спецификации, которые вы задаете для StartFcnSpec
, InitializeConditionsFcnSpec
или TerminateFcnSpec
, не могут получить доступ к аргументам ввода или вывода. Для StartFcnSpec
и InitializeConditionsFcnSpec
, можно получить доступ к выходным портам, если опция S-функции outputsConditionallyWritten
установлена в true
. С этой установкой опции сгенерированная S-функция указывает, что память, сопоставленная с каждым выходным портом, не может быть перезаписана и глобальна (SS_NOT_REUSABLE_AND_GLOBAL
).
После того, как вы укажете структуру данных Legacy Code Tool для существующей функции C, используйте функцию legacy_code
, как объяснено ниже, чтобы сгенерировать, скомпилировать, и соединить S-функцию.
Сгенерируйте S-функцию MEX C на основе информации, заданной в структуре. Вызовите legacy_code
с 'sfcn_cmex_generate'
в качестве первого аргумента и имени структуры данных в качестве второго аргумента.
legacy_code('sfcn_cmex_generate', lct_spec);
Скомпилируйте и соедините S-функцию. Этот шаг принимает, что компилятор C настраивается для вашей установки MATLAB. Вызовите legacy_code
с 'compile'
в качестве первого аргумента и имени структуры данных в качестве второго аргумента.
legacy_code('compile', lct_spec);
Информационные сообщения, подобные следующему, появляются в окне команды MATLAB, и заканчивается динамически загружаемый исполняемый файл. В 32-битной системе Windows, названия программного обеспечения Simulink файл ex_sfun_doubleit.mexw32
.
### Start Compiling ex_sfun_doubleit mex ex_sfun_doubleit.c -Id:\work\lct\lct_demos ### Finish Compiling ex_sfun_doubleit ### Exit
Как удобство, можно сгенерировать, скомпилировать и соединить S-функцию на одном шаге путем вызова legacy_code
с вектором символов 'generate_for_sim'
. Функция также генерирует файл TLC для ускоренных симуляций, если поле Options.useTlcWithAccel
структуры данных Legacy Code Tool установлено в 1.
Если вы сгенерировали динамически загружаемый исполняемый файл, вы или другие можете использовать его в модели путем добавления Блока s-function, который задает скомпилированную S-функцию.
У вас есть опция использования Legacy Code Tool, чтобы сгенерировать Блок s-function маскированный (графическое представление), которое сконфигурировано, чтобы вызвать сгенерированную S-функцию MEX C. Чтобы сгенерировать такой блок, вызовите legacy_code
с 'slblock_generate'
в качестве первого аргумента и имени структуры данных Legacy Code Tool в качестве второго аргумента.
legacy_code('slblock_generate', lct_spec);
Инструмент маскирует блок, таким образом, что это отображает значение поля OutputFcnSpec
. Можно затем добавить блок в модель вручную.
Если вы предпочитаете, чтобы Legacy Code Tool добавил блок в модель автоматически, задал имя модели в качестве третьего аргумента. Например:
legacy_code('slblock_generate', lct_spec, 'myModel');
Если заданная модель (например, myModel
) существует, legacy_code
открывает модель и добавляет Блок s-function маскированный, описанный структурой данных Legacy Code Tool. Если модель не существует, функция создает новую модель с указанным именем и добавляет Блок s-function маскированный.
Если вы используете режим Simulink Accelerator™, можно сгенерировать и обеспечить использование TLC встраивание кода для S-функции, сгенерированной Legacy Code Tool. Для этого:
Сгенерируйте файл блока TLC для S-функции путем вызывания функции legacy_code
с 'sfcn_tlc_generate'
в качестве первого аргумента и имени структуры данных Legacy Code Tool в качестве второго аргумента.
legacy_code('sfcn_tlc_generate', lct_spec);
Полагайте, что пример в Интегрирует Функции C в Модели Simulink с Legacy Code Tool. Чтобы сгенерировать файл TLC для модели, показанной в конце того примера, введите следующую команду:
legacy_code('sfcn_tlc_generate', def);
Обеспечьте Режим Accelerator, чтобы использовать файл TLC при помощи
функции SimStruct
ssSetOptions
, чтобы установить опцию S-функции SS_OPTION_USE_TLC_WITH_ACCELERATOR
.
Чтобы вызвать устаревшую функцию C++ после инициализации структуры данных Legacy Code Tool, присвойте значение 'C++' полю Options.language
. Например,
def = legacy_code('initialize'); def.Options.language = 'C++';
Чтобы проверить новую установку, войти
def.Options.language
Legacy Code Tool может взаимодействовать через интерфейс с функциями C++, но не объектами C++. Для работы вокруг, смотрите Ограничения Legacy Code Tool в документации Simulink.
Вы можете иметь несколько регистрационных файлов в той же папке и сгенерировать S-функцию для каждого файла с одним вызовом legacy_code
. Аналогично, можно использовать один вызов legacy_code
в порядке скомпилировать и соединить S-функции и другого, чтобы сгенерировать соответствующие файлы блока TLC, в подходящих случаях.
Рассмотрите следующий пример, где lct_register_1
, lct_register_2
и lct_register_3
каждый создает и инициализирует поля структуры Legacy Code Tool.
defs1 = lct_register_1; defs2 = lct_register_2; defs3 = lct_register_3; defs = [defs1(:);defs2(:);defs3(:)];
Можно затем использовать следующую последовательность вызовов legacy_code
в порядке сгенерировать файлы на основе трех регистрационных файлов:
legacy_code('sfcn_cmex_generate', defs); legacy_code('compile', defs); legacy_code('sfcn_tlc_generate', defs);
Также можно обработать каждый регистрационный файл отдельно. Например:
defs1 = lct_register1; legacy_code('sfcn_cmex_generate', defs1); legacy_code('compile', defs1); legacy_code('sfcn_tlc_generate', defs1); . . . defs2 = lct_register2; legacy_code('sfcn_cmex_generate', defs2); legacy_code('compile', defs2); legacy_code('sfcn_tlc_generate', defs2); . . . defs3 = lct_register3; legacy_code('sfcn_cmex_generate', defs3); legacy_code('compile', defs3); legacy_code('sfcn_tlc_generate', defs3);
Можно развернуть S-функции, которые вы генерируете с Legacy Code Tool для использования другими. Чтобы развернуть S-функцию для симуляции используют только, необходимо совместно использовать только скомпилированный динамически загружаемый исполняемый файл.
Чтобы видеть примеры Legacy Code Tool, в окне команды MATLAB, введите:
Примеры Legacy Code Tool перечислены в Моделировании Функций> Авторские блоки с S-функциями, Системными объектами и Legacy Code Tool.
Legacy Code Tool
Генерирует S-функции MEX C для существующих функций, написанных в C или C++. Инструмент не поддерживает преобразование функций MATLAB или Фортрана.
Может взаимодействовать через интерфейс с функциями C++, но не объектами C++. Один способ работать вокруг этого ограничения состоит в том, чтобы использовать Разработчика S-функции, чтобы сгенерировать интерпретатор S-функции и затем вызвать устаревший Код С++ от функции обратного вызова mdlOutputs
S-функции.
Не поддерживает моделирующие непрерывные или дискретные состояния. Это препятствует тому, чтобы вы использовали функции обратного вызова mdlDerivatives
и mdlUpdate
. Если ваше приложение требует этой поддержки, смотрите Используя Разработчика S-функции, чтобы Включить Унаследованный код.
Всегда устанавливает флаг S-функций для прямого сквозного соединения (sizes.DirFeedthrough
) к true
. Из-за этой установки и предыдущего ограничения, сгенерированная S-функция не может повредить алгебраические циклы.
Поддержки только непрерывное, но зафиксированный в незначительном временном шаге, шаге расчета и опции смещения.
Комплексные числа поддержек, но только с Simulink встроенные типы данных.
Не поддерживает использование указателей функции как вывод устаревшей вызванной функции.
Не поддерживает следующие функции S-функции:
Векторы работы, кроме векторов генерала Дуорка
Основанные на кадре сигналы ввода и вывода
Основанные на порте шаги расчета
Несколько основанных на блоке шагов расчета
Не поддерживает использование осциллографа (: :) оператор для доступа данных о классе C++ и методов. Для статических методов можно записать простые макросы препроцессора, подобные следующему, чтобы работать вокруг этого:
#define CCommon_computeVectorDotProduct CCommon::computeVectorDotProduct