timesN Обзор примера по цикличному выполнениюObjective: В этом примере показано, как можно влиять на поведение цикличного выполнения сгенерированного кода.
Folder:
открытыйmatlabroot/toolbox/rtw/rtwdemos/tlctutorial/timesN
Работа с моделью sfun_xN в tlctutorial/timesN. Это имеет один источник (блок генератора Sine Wave), блок усиления times 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;
Библиотечные функции TLC LibBlockInputSignal и LibBlockOutputSignal расширьтесь, чтобы произвести скалярные или векторные идентификаторы, которые называют и индексируют. LibBlockInputSignal, LibBlockOutputSignal, и много имели отношение, функции TLC передаются четыре канонических аргумента:
| Аргумент | Описание |
|---|---|
первый аргумент — | Соответствует индексу входного порта для данного блока. Первый входной порт имеет индекс 0. Второй входной порт имеет индекс 1 и так далее. |
второй аргумент — | Индексная переменная зарезервирована для усовершенствованного использования. На данный момент задайте второй аргумент как пустую строку. В усовершенствованных приложениях можно задать собственное имя переменной, которое будет использоваться в качестве индекса с |
третий аргумент — | Аналогичный описанному ранее, |
четвертый аргумент — | Позволяет TLC обработать особые случаи. Если |