Встроить S-функцию означает предоставить файл TLC для блока S-функции, который заменит версию блока на языке C, C++, Fortran или MATLAB ®, которая использовалась во время моделирования.
Если встроенный файл TLC не предоставляется, большинство целевых объектов поддерживают блок, перекомпилируя S-функцию C MEX для блока. Как обсуждалось ранее, при использовании кодированной C/C + + S-функции и ограниченного подмножества существует служебная нагрузка в использовании памяти и скорости.mx* Вызовы API поддерживаются в контексте генератора кода. Если требуется наиболее эффективный сгенерированный код, необходимо встроить S-функции, написав для них файл TLC.
При необходимости выполнения одной из функций для S-функционального блока вызывается MEX-файл для этой функции. Когда генератор кода выполняет неинлиннированную S-функцию, он делает это аналогичным образом, как показывает эта диаграмма.


Полезно определить две категории встраивания:
Полностью встроенные S-функции
Обертка встроенных S-функций
Несмотря на то, что обе S-функции встроены в линию, а служебные данные неинлинной S-функции удалены, эти два подхода различны. Первый пример ниже, использование timestwo.tlc, считается полностью встроенным TLC-файлом, где полная реализация блока содержится в TLC-файле для блока.
Во втором примере используется TLC-файл оболочки. Вместо генерации алгоритмического кода на месте в этом примере вызывается функция C, которая содержит тело кода. Существует несколько потенциальных преимуществ использования TLC-файла оболочки:
Она обеспечивает способ совместного использования C MEX S-функции и сгенерированного кода. Вам не нужно писать код дважды.
Вызываемая функция C является оптимизированной подпрограммой.
Несколько блоков могут существовать в модели, и более эффективно с точки зрения размера кода, чтобы они вызывали функцию, в отличие от каждого создания идентичного алгоритмического кода.
Она обеспечивает способ прозрачного включения унаследованного кода C в сгенерированный код.
Встраивание S-функции обеспечивает механизм непосредственного встраивания кода для S-функционального блока в сгенерированный код для модели. Вместо того, чтобы вызывать отдельный исходный файл через указатели функций и поддерживать отдельную структуру данных (SimStruct) для него код отображается «встроенным», как показано на следующем рисунке.

S-функция timestwo.c предоставляет простой пример полностью встроенной S-функции. Этот блок умножает свой вход на 2 и выводит его. Версия блока C MEX находится в файле , и вложенный файл 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
В этой простой модели используется timestwo S-функция и показывает 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.hmyfile.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;
}