Встроить S-функцию означает предоставить файл TLC для блока S-Function, который заменит C, C++, Фортран или MATLAB® языковая версия блока, которая использовалась во время симуляции.
Если встроенный файл не предусмотрен, большинство целей поддерживают блок путем перекомпиляции S-функции C MEX для блока. Как обсуждалось ранее, в использовании памяти и скорости при использовании кодированной S-функции C/C + + и ограниченного подмножества mx*
Вызовы API, поддерживаемые в контексте генератора кода. Если вам нужен самый эффективный сгенерированный код, необходимо встроить S-функции, записав для них файл.
Когда симуляции нужно выполнить одну из функций для блока s-function, она вызывает файл MEX для этой функции. Когда генератор кода выполняет нелинейную S-функцию, он делает это подобным образом, как иллюстрирует эта схема.
Полезно определить две категории встраивания:
Полностью встроенные S-функции
Оболочка встроенных S-функций
В то время как как встроенная S-функция, так и удаление накладных расходов неинлинфицированной S-функции, эти два подхода различны. Первый пример ниже, использование timestwo.tlc
, рассматривается как полностью встроенный файл TLC, где полная реализация блока содержится в файле TLC для блока.
Во втором примере используется файл TLC оболочки. Вместо того, чтобы сгенерировать алгоритмический код на месте, этот пример вызывает функцию C, которая содержит тело кода. Существует несколько потенциальных преимуществ для использования файла wrapper TLC:
Он предоставляет способ для S-функции C MEX и сгенерированного кода совместно использовать код C. Вам не нужно писать код дважды.
Вызываемая функция C является оптимизированной стандартной программой.
Несколько блоков могут существовать в модели, и с точки зрения размера кода более эффективно, чтобы они вызывали функцию, в отличие от каждого создания идентичного алгоритмического кода.
Он предоставляет способ плавного включения унаследованного кода С в сгенерированный код.
Вставка S-функции предоставляет механизм для непосредственного встраивания кода для блока s-function в сгенерированный код для модели. Вместо вызова в отдельный исходный файл через указатели на функцию и поддержания отдельной структуры данных (SimStruct
) для него код появляется «inlined», как показано на следующем рисунке.
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
The %implements
директива требуется для файлов блоков TLC и используется компилятором целевого языка для проверки типа блоков и языка, поддерживаемых блоком. The %function
директива запускает объявление функции и показывает имя функции, Outputs
, и аргументы перешли к нему, block
и system
. Это соответствующие записи из
файл для этого образца блока.model
.rtw
Последняя часть прототипа Output
. Это означает, что любая линия, которая не является директивой TLC, выводится функцией в текущий файл, который выбран в TLC. Итак, ненаправленные линии в Outputs
function станьте сгенерированным кодом для блока.
Самый сложный кусок этого примера блока 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; }