Инкрустация S-функций

Инкрустация S-функции

Встроить S-функцию означает предоставить файл TLC для блока S-Function, который заменит C, C++, Фортран или MATLAB® языковая версия блока, которая использовалась во время симуляции.

Нелинейная S-функция

Если встроенный файл не предусмотрен, большинство целей поддерживают блок путем перекомпиляции 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-функции предоставляет механизм для непосредственного встраивания кода для блока s-function в сгенерированный код для модели. Вместо вызова в отдельный исходный файл через указатели на функцию и поддержания отдельной структуры данных (SimStruct) для него код появляется «inlined», как показано на следующем рисунке.

S-функция timestwo.c предоставляет простой пример полностью встроенной S-функции. Этот блок умножает свой вход на 2 и выводит его. Версия блока на C MEX находится в файле matlabroot/ toolbox/simulink/simdemos/simfeatures/src/timestwo.c, и входящий TLC- файла для блока matlabroot/ toolbox/simulink/simdemos/simfeatures/tlc_c/timestwo.tlc.

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

Анализ блоков TLC

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

Эта простая модель использует timestwo S-функция и показывает MdlOutputs функцию от сгенерированного model.c файл, который содержит встроенный код S-функции.

Код выходов модели

/* 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-функции в качестве оболочки. Алгоритм непосредственно вызывается из сгенерированного кода модели, удаляя накладные расходы 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;
}

Похожие темы