Встраивать S-функцию означает обеспечивать файл TLC для Блока s-function, который заменит C, C++, Фортран или версию языка MATLAB® блока, который использовался во время симуляции.
Если встраивание, которое файл TLC не обеспечивается, большинство целей, поддерживает блок путем перекомпиляции S-функции MEX C для блока. Как обсуждено ранее, существуют издержки в использовании памяти, и скорость при использовании C/C++ закодировала S-функцию и ограниченное подмножество вызовов API mx*
, поддержанных в контексте генератора кода. Если вы хотите самый эффективный сгенерированный код, необходимо встроить S-функции путем записывания файла TLC для них.
Когда симуляция должна выполнить одну из функций для Блока s-function, это вызывает файл MEX для этой функции. Когда генератор кода выполняет невстроенную S-функцию, он делает так подобным образом, как эта схема иллюстрирует.
Полезно задать две категории встраивания:
Полностью встроенные S-функции
Обертка встроила S-функции
В то время как и встроенный S-функция и удаляет издержки невстроенной S-функции, два подхода отличаются. Первый пример ниже, с помощью timestwo.tlc
, рассматривается полностью встроенным файлом TLC, где полное внедрение блока содержится в файле TLC для блока.
Второй пример использует обертку файл TLC. Вместо того, чтобы генерировать алгоритмический код на месте, этот пример вызывает функцию C, которая содержит тело кода. Существует несколько потенциальных выгод для использования обертки файл TLC:
Это обеспечивает путь к S-функции MEX C и сгенерированному коду, чтобы совместно использовать код С. Вы не должны писать код дважды.
Вызванная функция C является оптимизированной стандартной программой.
Несколько из блоков могут существовать в модели, и более эффективно с точки зрения размера кода сделать, чтобы они вызвали функцию, в противоположность каждому создающему идентичному алгоритмическому коду.
Это обеспечивает способ включить устаревший код С беспрепятственно в сгенерированный код.
Встраивание S-функции предоставляет механизм непосредственно встроенному коду для Блока s-function в сгенерированный код для модели. Вместо того, чтобы вызвать в отдельный исходный файл через указатели функции и поддержать отдельную структуру данных (SimStruct
) для него, код кажется “встроенным”, когда следующие данные показывают.
S-функция timestwo.c
обеспечивает простой пример полностью встроенной S-функции. Этот блок умножает свой вход на 2 и выводит его. Версия MEX C блока находится в файле
и встраивание, файлом TLC для блока является matlabroot/toolbox/simulink/simdemos/simfeatures/src/timestwo.c
.matlabroot/toolbox/simulink/simdemos/simfeatures/tlc_c/timestwo.tlc
%implements "timestwo" "C" %% Function: Outputs ========================================== %% %function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %% /* Multiply input by two */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal(0, "", lcv, idx)> * 2.0; %endroll %endfunction
Директива %implements
требуется файлами блока TLC и используется целевым Языковым компилятором, чтобы проверить тип блока и язык, поддержанный блоком. Директива %function
запускает объявление функции и показывает имя функции, Outputs
, и аргументы передали ему, block
и system
. Это соответствующие записи из файла
для этого экземпляра блока.model.rtw
Последней частью прототипа является Output
. Это означает, что любая строка, которая не является директивой TLC, выводится функцией к текущему файлу, который выбран в TLC. Так, ненаправленные строки в функции Outputs
становятся сгенерированным кодом для блока.
Самая сложная часть этого примера блока TLC является директивой %roll
. TLC использует эту директиву, чтобы обеспечить автоматическую генерацию циклов for
, в зависимости от ширин ввода/вывода и непрерывны ли входные параметры в памяти. Этот пример использует типичную форму доступа к выходным параметрам и вводит из тела списка, с помощью LibBlockOutputSignal
и LibBlockInputSignal
, чтобы получить доступ к выходным параметрам и входным параметрам и выполнить умножение и присвоение. Обратите внимание на то, что этот файл TLC поддерживает любую допустимую ширину сигнала.
Единственной функцией, используемой, чтобы реализовать этот блок, является Outputs
. Для более сложных блоков другие функции объявляются также. Можно найти примеры более сложного встраивания файлами TLC в папках
(открытый) и matlabroot/toolbox/simulink/simdemos/simfeatures/tlc_c
(открытый), и путем рассмотрения кода для встроенных блоков в matlabroot/toolbox/simulink/blocks/tlc_c
(открытой)
папке
.matlabroot/rtw/c/tlc/blocks
Эта простая модель использует S-функцию timestwo
и показывает функцию MdlOutputs
из сгенерированного файла
, который содержит встроенный код S-функции.model.c
/* Model output function */ static void timestwo_ex_output(int_T tid) { /* S-Function Block: <Root>/S-Function */ /* Multiply input by two */ timestwo_ex_B.timestwo_output = timestwo_ex_P.Constant_Value * 2.0; /* Outport: '<Root>/Out1' */ timestwo_ex_Y.Out1 = timestwo_ex_B.timestwo_output; }
Следующая схема иллюстрирует встраивание S-функции как обертка. Алгоритм непосредственно называется из сгенерированного типового кодекса, удаляя S-функцию наверху, но поддерживая функцию пользователя.
Это - встраивание файл TLC для версии обертки блока timestwo
.
%implements "timestwo" "C" %% Function: BlockTypeSetup ================================== %% %function BlockTypeSetup(block, system) void %% Add function prototype to model's header file %<LibCacheFunctionPrototype... ("extern void mytimestwo(real_T* in,real_T* out,int_T els);")> %% Add file that contains "myfile" to list of files to be compiled %<LibAddToModelSources("myfile")> %endfunction %% Function: Outputs ========================================== %% %function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %assign outPtr = LibBlockOutputSignalAddr(0, "", "", 0) %assign inPtr = LibBlockInputSignalAddr(0, "", "",0) %assign numEls = LibBlockOutputSignalWidth(0) /* Multiply input by two */ mytimestwo(%<inPtr>,%<outPtr>,%<numEls>); %endfunction
Функциональный BlockTypeSetup
называется однажды для каждого типа блока в модели; это не производит вывод непосредственно как функция Outputs
. Используйте BlockTypeSetup
, чтобы включать прототипа функции в файл
и сказать процессу сборки компилировать дополнительный файл, model.h
myfile.c
.
Вместо того, чтобы выполнить умножение непосредственно, функция Outputs
теперь вызывает функциональный mytimestwo
. Все экземпляры этого блока в модели вызывают ту же функцию, чтобы выполнить умножение. Получившаяся образцовая функция, MdlOutputs
, затем становится
static void timestwo_ex_output(int_T tid) { /* S-Function Block: <Root>/S-Function */ /* Multiply input by two */ mytimestwo(&model_B.Constant_Value,&model_B.S_Function,1); /* Outport Block: <Root>/Out1 */ model_Y.Out1 = model_B.S_Function; }