timesNObjective:, который показывает Этот пример, как можно влиять на поведение цикличного выполнения сгенерированного кода.
Folder: (открытый) matlabroot/toolbox/rtw/rtwdemos/tlctutorial/timesN
Работа с моделью sfun_xN в tlctutorial/timesN. Это имеет один источник (блок генератора Синусоиды), времена N блок усиления, блок Out и блок Scope.
Пример проводит вас по следующим шагам:
Начало работы Настройте осуществление и запустите модель
Modify the Model — Измените вход width и смотрите результаты
Change the Loop Rolling Threshold — Измените порог и смотрите результаты
More About TLC Loop Rolling — Параметризуйте поведение цикла
Сделайте tlctutorial/timesN вашей текущей папкой, так, чтобы можно было использовать обеспеченные файлы.
Необходимо использовать или создать рабочую папку за пределами для моделей Simulink®, которые вы делаете. Вы не можете создать модели в исходных папках.matlabroot
В Командном окне MATLAB® создайте файл MEX для S-функции:
mex timesN.c
Это старается не брать версию, поставленную с Simulink.
Ошибка может произойти, если вы ранее не запустили mex -setup.
Откройте образцовый файл sfun_xN.

Просмотрите ранее сгенерированный код в sfun_xN_grt_rtw/sfun_xN.c. Обратите внимание на то, что никакие циклы не существуют в коде. Это вызвано тем, что сигналы ввода и вывода являются скаляром.
Замените блок Sine Wave на блок Constant.
Установите параметр для блока Constant к 1:4 и измените главную метку, model: sfun_xN, к model: sfun_vec.
Сохраните отредактированную модель как sfun_vec (в tlctutorial/timesN). Модель теперь выглядит так.

Поскольку блок Constant генерирует вектор значений, это - векторизованная модель. Сгенерируйте код для модели и просмотрите раздел /*Model output function */ sfun_vec.c в вашем редакторе, чтобы наблюдать, как обработаны переменные и циклы for. Эта функция появляется можно следующим образом:
/* Model output function */
static void sfun_vec_output(int_T tid)
{
/* S-Function Block: <Root>/S-Function */
/* Multiply input by 3.0 */
sfun_vec_B.timesN_output[0] = sfun_vec_P.Constant_Value[0] * 3.0;
sfun_vec_B.timesN_output[1] = sfun_vec_P.Constant_Value[1] * 3.0;
sfun_vec_B.timesN_output[2] = sfun_vec_P.Constant_Value[2] * 3.0;
sfun_vec_B.timesN_output[3] = sfun_vec_P.Constant_Value[3] * 3.0;
/* Outport: '<Root>/Out' */
sfun_vec_Y.Out[0] = sfun_vec_B.timesN_output[0];
sfun_vec_Y.Out[1] = sfun_vec_B.timesN_output[1];
sfun_vec_Y.Out[2] = sfun_vec_B.timesN_output[2];
sfun_vec_Y.Out[3] = sfun_vec_B.timesN_output[3];
UNUSED_PARAMETER(tid);
}Заметьте, что существует четыре экземпляра кода, который генерирует образцовые выходные параметры, соответствуя четырем итерациям.
Установите параметр для блока Constant к 1:10 и сохраните модель.
Сгенерируйте код для модели и просмотрите раздел /*Model output function */ sfun_vec.c в вашем редакторе, чтобы наблюдать, как обработаны переменные и циклы for. Эта функция появляется можно следующим образом:
/* Model output function */
static void sfun_vec_output(int_T tid)
{
/* S-Function Block: <Root>/S-Function */
/* Multiply input by 3.0 */
{
int_T i1;
const real_T *u0 = &sfun_vec_P.Constant_Value[0];
real_T *y0 = sfun_vec_B.timesN_output;
for (i1=0; i1 < 10; i1++) {
y0[i1] = u0[i1] * 3.0;
}
}
{
int32_T i;
for (i = 0; i < 10; i++) {
/* Outport: '<Root>/Out' */
sfun_vec_Y.Out[i] = sfun_vec_B.timesN_output[i];
}
}
UNUSED_PARAMETER(tid);
}Заметьте что:
Код, который генерирует образцовые выходные параметры, “прокручивается” в цикл. Это происходит по умолчанию, когда количество итераций превышает 5.
Индекс цикла i1 запускается от 0 до 9.
Указатель *y0 используется и инициализируется к массиву выходного сигнала.
Генератор кода создает итерации или циклы в зависимости от текущего значения параметра Loop unrolling threshold.
Значением по умолчанию Loop unrolling threshold является 5. Изменить поведение цикличного выполнения для блоков в модели:
На панели Optimization диалогового окна Configuration Parameters, набор Loop unrolling threshold к 12 и нажимают Apply.
Параметром RollThreshold является теперь 12. Циклы будут сгенерированы только, когда ширина сигналов, проходящих через блок, превысит 12.
Вы не можете изменить RollThreshold для определенных блоков от диалогового окна Configuration Parameters.
Нажмите Ctrl+B, чтобы регенерировать вывод.
Осмотрите sfun_vec.c. Это будет выглядеть так:
/* Model output function */
static void sfun_vec_output(int_T tid)
{
/* S-Function Block: <Root>/S-Function */
/* Multiply input by 3.0 */
sfun_vec_B.timesN_output[0] = sfun_vec_P.Constant_Value[0] * 3.0;
sfun_vec_B.timesN_output[1] = sfun_vec_P.Constant_Value[1] * 3.0;
sfun_vec_B.timesN_output[2] = sfun_vec_P.Constant_Value[2] * 3.0;
sfun_vec_B.timesN_output[3] = sfun_vec_P.Constant_Value[3] * 3.0;
sfun_vec_B.timesN_output[4] = sfun_vec_P.Constant_Value[4] * 3.0;
sfun_vec_B.timesN_output[5] = sfun_vec_P.Constant_Value[5] * 3.0;
sfun_vec_B.timesN_output[6] = sfun_vec_P.Constant_Value[6] * 3.0;
sfun_vec_B.timesN_output[7] = sfun_vec_P.Constant_Value[7] * 3.0;
sfun_vec_B.timesN_output[8] = sfun_vec_P.Constant_Value[8] * 3.0;
sfun_vec_B.timesN_output[9] = sfun_vec_P.Constant_Value[9] * 3.0;
/* Outport: '<Root>/Out' */
sfun_vec_Y.Out[0] = sfun_vec_B.timesN_output[0];
sfun_vec_Y.Out[1] = sfun_vec_B.timesN_output[1];
sfun_vec_Y.Out[2] = sfun_vec_B.timesN_output[2];
sfun_vec_Y.Out[3] = sfun_vec_B.timesN_output[3];
sfun_vec_Y.Out[4] = sfun_vec_B.timesN_output[4];
sfun_vec_Y.Out[5] = sfun_vec_B.timesN_output[5];
sfun_vec_Y.Out[6] = sfun_vec_B.timesN_output[6];
sfun_vec_Y.Out[7] = sfun_vec_B.timesN_output[7];
sfun_vec_Y.Out[8] = sfun_vec_B.timesN_output[8];
sfun_vec_Y.Out[9] = sfun_vec_B.timesN_output[9];
UNUSED_PARAMETER(tid);
}Чтобы активировать цикл, прокручивающийся снова, измените Loop unrolling threshold на 10 (или меньше) на панели Optimization.
Прокрутка цикла является важной возможностью TLC оптимизации сгенерированного кода. Не торопитесь, чтобы изучить и исследовать его последствия прежде, чем сгенерировать код для производственных требований.
Следующий код %roll TLC является функцией Outputs timesN.tlc:
%function Outputs(block, system) Output
/* %<Type> Block: %<Name> */
%%
/* Multiply input by %<gain> */
%assign rollVars = ["U", "Y"]
%roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
%<LibBlockOutputSignal(0, "", lcv, idx)> = \
%<LibBlockInputSignal(0, "", lcv, idx)> * %<gain>;
%endroll
%endfunction %% Outputs%rollСтроки между %roll и %endroll могут быть или повторены или циклично выполнены. Ключ к пониманию директивы %roll находится в ее аргументах:
%roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
| Аргумент | Описание |
|---|---|
sigIdx | Задайте индекс в вектор (сигнала), который используется в сгенерированном коде. Если сигнал является скаляром, анализируя тот блок |
lcv | Контрольная переменная обычно задана в директиве |
block | Это говорит TLC, что он работает с объектами блока. Код TLC для S-функций использует этот аргумент. |
"Roller" | Это, заданное в |
rollVars | Говорит TLC, какие типы элементов должны быть прокручены: входные сигналы, выходные сигналы и/или параметры. Вы не должны использовать всех их. В предыдущей строке %assign rollVars = ["U", "Y"] U) и выходные сигналы (Y). В случаях, где блоки задают массив параметров вместо скалярного параметра, rollvars задан как%assign rollVars = ["U", "Y", "P"] |
Посмотрите на строки, которые появляются между %roll и %endroll:
%<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal (0, "", lcv, idx)> * 2.0;
LibBlockInputSignal библиотечных функций TLC и LibBlockOutputSignal расширяются, чтобы произвести скалярные или векторные идентификаторы, которые называют и индексируют. LibBlockInputSignal, LibBlockOutputSignal, и много имели отношение, функции TLC передаются четыре канонических аргумента:
| Аргумент | Описание |
|---|---|
первый аргумент — | Соответствует индексу входного порта для данного блока. Первый входной порт имеет индекс 0. Второй входной порт имеет индекс 1 и так далее. |
второй аргумент — | Индексная переменная зарезервирована для усовершенствованного использования. На данный момент задайте второй аргумент как пустую строку. В усовершенствованных приложениях можно задать собственное имя переменной, которое будет использоваться в качестве индекса с |
третий аргумент — | Как описано ранее, |
четвертый аргумент — | Позволяет TLC обработать особые случаи. Если |