Более сложные S-функции можно встроить с помощью S-функции. mdlRTW рутина. mdlRTW подпрограмма предоставляет процессу генерации кода более подробную информацию о том, как S-функция должна быть встроена путем создания записи параметров неперестраиваемого параметра для использования с TLC-файлом. mdlRTW рутинные места информация в файл. model.rtwmdlRTW функция описана в текстовом файле .matlabroot/simulink/src/sfuntmpl_doc.c
Для использования mdlRTW выполните шаги для создания S-функции поиска прямого индекса. Таблицы подстановки представляют собой коллекции упорядоченных точек данных функции. Обычно эти таблицы используют некоторую схему интерполяции для аппроксимации значений связанной функции между известными точками данных. Чтобы включить пример алгоритма таблицы поиска в модель Simulink ®, первым шагом является запись S-функции, которая выполняет алгоритм вmdlOutputs. Чтобы создать наиболее эффективный код, следующим шагом является создание соответствующего файла TLC, чтобы исключить вычислительные издержки и улучшить скорость вычислений поиска.
Продукт Simulink оказывает поддержку для поиска общего назначения 1-D, 2-х, и n-D алгоритмов. Эти алгоритмы можно использовать как таковые или создать пользовательскую S-функцию таблицы подстановки в соответствии с вашими требованиями. Можно создать S-функцию поиска 1-D, sfun_directlook.c, и его соответствующие встроенные sfun_directlook.tlc (дополнительные сведения см. в разделе Компилятор целевого языка). Вы можете:
Ошибка проверки параметров S-функции.
Информация кэша для S-функции, которая не изменяется во время выполнения модели.
Используйте mdlRTW настройка генератора кода для получения оптимального кода для заданного набора параметров блока.
Создать TLC файл для S-функции, которая либо полностью встраивает код таблицы поиска, либо вызывает функцию-оболочку для алгоритма таблицы поиска.
RTWdata является свойством блоков, которое может использоваться компилятором целевого языка при встраивании S-функции. RTWdata - структура символьных векторов, которую можно присоединить к блоку. RTWdata сохраняется вместе с моделью и помещается в при создании кода. Например, этот набор команд MATLAB ®:model.rtw
mydata.field1 = 'information for field1'; mydata.field2 = 'information for field2'; set_param(gcb,'RTWdata',mydata) get_param(gcb,'RTWdata')
дает следующий результат:
ans =
field1: 'information for field1'
field2: 'information for field2'Информация для связанного блока S-Function внутри файл:model.rtw
Block {
Type "S-Function"
RTWdata {
field1 "information for field1"
field2 "information for field2"
}Примечание
RTWdata сохраняется в файле модели для S-функций, не связанных с библиотекой. Однако RTWdata не является постоянным для S-функциональных блоков, связанных с библиотекой.
Блок таблицы поиска 1-D, предоставленный в библиотеке Simulink, использует интерполяцию или экстраполяцию при вычислении выходных данных. В этом примере создается таблица подстановки, которая непосредственно индексирует выходной вектор (вектор y-данных) на основе текущей входной точки (x-данных).
Этот пример прямого поиска 1-D вычисляет приблизительное решение p (x) для частично известной функции f (x) при x = x0, заданные пары точек данных (x, y) в виде вектора x-данных и вектора y-данных. Для данной пары данных (например, i-ой пары) y_i = f (x_i). Предполагается, что значения x-данных монотонно увеличиваются. Если x0 находится вне диапазона вектора x-данных, возвращается первая или последняя точка.
Параметры для S-функции:
XData, YData, XEvenlySpaced
XData и YData - двойные векторы равной длины, представляющие значения неизвестной функции. XDataEvenlySpaced является скаляром, 0.0 для false и 1.0 для true. Если XData вектор равномерно разнесен, XDataEvenlySpaced является 1.0 и формируют более эффективный код.
На графике показано, как параметры XData=[1:6]и YData=[1,2,7,4,5,9] обрабатываются. Например, если входное значение (x-значение) блока S-функции равно 3, то выходное значение (y-значение) равно 7.

Улучшите таблицу подстановки, встроив S-функцию прямого индекса в файл TLC. Эта таблица поиска прямого индекса S-функция не требует файла TLC. В примере используется файл TLC для S-функции поиска прямого индекса для уменьшения размера кода и повышения эффективности генерируемого кода.
Для реализации алгоритма прямого индекса с встроенным TLC-файлом требуется основной модуль S-функции, sfun_directlook.c и соответствующий lookup_index.c модуль. lookup_index.c модуль содержит GetDirectLookupIndex функция, которая используется для поиска индекса в XData для текущего x входное значение при XData неравномерно разнесен. GetDirectLookupIndex вызывается подпрограмма из S-функции и сгенерированного кода. В примере используется концепция обертки для совместного использования кода C/C + + между MEX-файлами Simulink и сгенерированным кодом.
Если XData равномерно распределяется, тогда и основной модуль S-функции, и сгенерированный код содержат алгоритм поиска для вычисления значения y данного значения x, поскольку алгоритм является коротким.
Встроенный файл TLC: sfun_directlook.tlc, который используется либо для выполнения вызова оболочки, либо для встраивания оптимального кода C/C + + для S-функции. (См. пример в разделе Использование mdlRTW).
В sfun_directlook.tlc, mdlCheckParameters процедура проверяет, что:
Новые параметры допустимы.
XData и YData - векторы одинаковой длины, содержащие вещественные конечные числа.
XDataEvenlySpaced является скаляром.
XData вектор - монотонно увеличивающийся вектор и равномерно разнесённый.
mdlInitializeSizes функция явно вызывает mdlCheckParameters после проверки количества параметров, переданных S-функции. После вызовов модуля Simulink mdlInitializeSizes, затем звонит mdlCheckParameters при каждом изменении параметров или их переоценке.
В sfun_directlook.tlc, mdlStart подпрограмма показывает, как кэшировать информацию, которая не изменяется во время моделирования или во время выполнения сгенерированного кода. В примере кэшируется значение XDataEvenlySpaced параметр в UserData, поле SimStruct. Следующая строка в mdlInitializeSizes предписывает модулю Simulink запретить изменения XDataEvenlySpaced.
ssSetSFcnParamTunable(S, iParam, SS_PRM_NOT_TUNABLE);
Во время выполнения, mdlOutputs получает доступ к значению XDataEvenlySpaced от UserData вместо вызова mxGetPr Функция API MATLAB.
Генератор кода вызывает mdlRTW во время генерации файл. Чтобы создать оптимальный код для модели Simulink, можно добавить информацию в model.rtw файл о режиме, в котором работает блок S-Function.model.rtw
Пример добавляет параметры к файл. Параметры не изменяются во время выполнения. В этом случае model.rtwXDataEvenlySpaced Параметр S-функции не может изменяться во время выполнения (ssSetSFcnParamTunable был указан как false (0) для него в mdlInitializeSizes). Настройка параметра (XSpacing) использует функцию ssWriteRTWParamSettings.
Поскольку xData и yData зарегистрированы как параметры времени выполнения в mdlSetWorkWidths, генератор кода записывает в автоматически.model.rtw
Прежде чем исследовать S-функцию и встроенный файл TLC, рассмотрите созданный код для этой модели.

Модель использует равномерно расположенные XData в верхнем S-функциональном блоке и неравномерно XData в нижнем блоке S-Function. При создании этой модели укажите следующие команды для каждого S-функционального блока.
set_param('sfun_directlook_ex/S-Function','SFunctionModules','lookup_index') set_param('sfun_directlook_ex/S-Function1','SFunctionModules','lookup_index')
В процессе построения используется модуль lookup_index.c при создании исполняемого файла.
При генерации кода для этой модели генератор кода использует S-функцию mdlRTW метод для создания файл со значением model.rtwEvenlySpaced для XSpacing параметр для верхнего блока S-Function и значение UnEvenlySpaced для XSpacing для нижнего блока S-Function. TLC-файл использует значение XSpacing определить, какой алгоритм следует включить в сгенерированный код. Сгенерированный код содержит алгоритм поиска, когда XData равномерно разнесен, но вызывает GetDirectLookupIndex подпрограмма, когда XData неравномерно разнесен. Произведенный или model.c код для модели примера таблицы подстановки аналогичен этому коду:model.cpp
/*
* sfun_directlook_ex.c
*
* Code generation for Simulink model
* "sfun_directlook_ex.slx".
*
...
*/
#include "sfun_directlook_ex.h"
#include "sfun_directlook_ex_private.h"
/* External outputs (root outports fed by signals with auto storage) */
ExtY_sfun_directlook_ex_T sfun_directlook_ex_Y;
/* Real-time model */
RT_MODEL_sfun_directlook_ex_T sfun_directlook_ex_M_;
RT_MODEL_sfun_directlook_ex_T *const sfun_directlook_ex_M =
&sfun_directlook_ex_M_;
/* Model output function */
void sfun_directlook_ex_output(void)
{
/* local block i/o variables */
real_T rtb_SFunction;
real_T rtb_SFunction1;
/* Sin: '<Root>/Sine Wave' */
rtb_SFunction1 = sin(sfun_directlook_ex_M->Timing.t[0]);
/* Code that is inlined for the top S-function block in the
* sfun_directlook_ex model
*/
/* S-Function (sfun_directlook): '<Root>/S-Function' */
{
const real_T *xData = sfun_directlook_ex_ConstP.SFunction_XData;
const real_T *yData = sfun_directlook_ex_ConstP.SFunction_YData;
real_T spacing = xData[1] - xData[0];
if (rtb_SFunction1 <= xData[0] ) {
rtb_SFunction = yData[0];
} else if (rtb_SFunction1 >= yData[20] ) {
rtb_SFunction = yData[20];
} else {
int_T idx = (int_T)( ( rtb_SFunction1 - xData[0] ) / spacing );
rtb_SFunction = yData[idx];
}
}
/* Outport: '<Root>/Out1' */
sfun_directlook_ex_Y.Out1 = rtb_SFunction;
/* Code that is inlined for the bottom S-function block in the
* sfun_directlook_ex model
*/
/* S-Function (sfun_directlook): '<Root>/S-Function1' */
{
const real_T *xData = sfun_directlook_ex_ConstP.SFunction1_XData;
const real_T *yData = sfun_directlook_ex_ConstP.SFunction1_YData;
int_T idx;
idx = GetDirectLookupIndex(xData, 5, rtb_SFunction1);
rtb_SFunction1 = yData[idx];
}
/* Outport: '<Root>/Out2' */
sfun_directlook_ex_Y.Out2 = rtb_SFunction1;
}
/* Model update function */
void sfun_directlook_ex_update(void)
{
/* signal main to stop simulation */
{ /* Sample time: [0.0s, 0.0s] */
if ((rtmGetTFinal(sfun_directlook_ex_M)!=-1) &&
!((rtmGetTFinal(sfun_directlook_ex_M)-sfun_directlook_ex_M->Timing.t[0])
> sfun_directlook_ex_M->Timing.t[0] * (DBL_EPSILON))) {
rtmSetErrorStatus(sfun_directlook_ex_M, "Simulation finished");
}
}
/* Update absolute time for base rate */
/* The "clockTick0" counts the number of times the code of this task has
* been executed. The absolute time is the multiplication of "clockTick0"
* and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
* overflow during the application lifespan selected.
* Timer of this task consists of two 32 bit unsigned integers.
* The two integers represent the low bits Timing.clockTick0 and the high bits
* Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
*/
if (!(++sfun_directlook_ex_M->Timing.clockTick0)) {
++sfun_directlook_ex_M->Timing.clockTickH0;
}
sfun_directlook_ex_M->Timing.t[0] = sfun_directlook_ex_M->Timing.clockTick0 *
sfun_directlook_ex_M->Timing.stepSize0 +
sfun_directlook_ex_M->Timing.clockTickH0 *
sfun_directlook_ex_M->Timing.stepSize0 * 4294967296.0;
}
...