Задайте буферное повторное использование при помощи Simulink. Объекты сигнала

Если ваша модель имеет оптимальные установки параметров для удаления копий данных, вы можете смочь удалить дополнительные копии данных при помощи объектов Simulink.Signal задать буферное повторное использование. После изучения сгенерированного кода и Статического Метрического Отчета Кода и идентификации областей, где вы думаете, буферное повторное использование возможно, вы задаете объекты сигнала на сигнальных линиях.

Можно задать буферное повторное использование на сигналах, которые включают пару корневого импорта и сигналов выходного порта. Можно также задать буферное повторное использование на только паре корневого импорта и сигналов выходного порта. Эта оптимизация уменьшает ROM и потребление RAM, потому что существуют менее глобальные переменные и копии данных в сгенерированном коде. Скорость выполнения кода также увеличивается.

Модель в качестве примера

Модель rtwdemo_reusable_csc содержит подсистему одноразового использования DeltaSubsystem и блок MATLAB function Downsample. DeltaSubsystem содержит блоки MATLAB function DeltaX и DeltaY.

model ='rtwdemo_reusable_csc';
open_system(model);

Задайте объект Simulink Signal для повторного использования

  1. В модели откройте Model Data Editor (Представление> Model Data Editor).

  2. В Model Data Editor, на вкладке Signals, от представления Change выпадающий список, выбирают Code.

  3. Нажмите кнопку дополнительной информации Show/refresh. Теперь, Model Data Editor показывает информацию о переменных и объектах в рабочих областях, таких как базовое рабочее пространство.

  4. Рядом с полем содержимого Фильтра активируйте Фильтр с помощью кнопки выбора.

  5. В модели выберите сигнальную линию RCSC_REAL. Model Data Editor показывает две строки: Тот, который представляет сигнальную линию и ту, которая представляет объект Simulink.Signal в базовом рабочем пространстве.

  6. Для строки, которая представляет сигнальную линию, осмотрите столбец Твердости. Флажок устанавливается, что значит твердость сигнальной линии для объекта Simulink.Signal, получая настройки генерации кода от того объекта.

  7. Для строки, которая представляет объект сигнала, осмотрите столбец Класса памяти. Объект сигнала использует класс памяти Reusable, что означает, что объект появляется в сгенерированном коде как глобальная переменная под названием RCSC_REAL.

  8. В модели перейдите в подсистему DeltaSubsystem.

  9. Выберите сигнальную линию RCSC_REAL в этой подсистеме. Этот сигнал также решает к объекту сигнала в базовом рабочем пространстве.

С классом памяти Reusable сгенерированный код может сохранить вывод блока Complex to Real-Imag (на корневом уровне модели) и вывод блока DeltaX (в подсистеме) в глобальной переменной RCSC_REAL.

Сгенерируйте код

Создайте модель.

currentDir = pwd;
[~,cgDir] = rtwdemodir();
rtwbuild(model);
### Starting build procedure for model: rtwdemo_reusable_csc
### Successful completion of build procedure for model: rtwdemo_reusable_csc

Для буферного повторного использования файл rtwdemo_reusable_csc.c содержит эти глобальные переменные:

  • static real_T RCSC_IMAG[1048576];

  • static real_T RCSC_IMAG2[262144];

  • static real_T RCSC_REAL[1048576];

  • static real_T RCSC_REAL2[262144];

Файл rtwdemo_reusable_csc.c содержит этот код:

cfile = fullfile(cgDir,...
    'rtwdemo_reusable_csc_ert_rtw','rtwdemo_reusable_csc.c');
rtwdemodbtype(cfile,...
    '/* Output and update for atomic system: ''<Root>/DeltaSubsystem'' */',...
    '/* Output and update for atomic system: ''<Root>/Downsample'' */',1,0);
rtwdemodbtype(cfile,...
    '/* Model step function */','/* Model initialize function */',1,0);
/* Output and update for atomic system: '<Root>/DeltaSubsystem' */
static void DeltaSubsystem(void)
{
  /* MATLAB Function: '<S1>/DeltaX' */
  DeltaX((&(RCSC_REAL2[0])), (&(RCSC_IMAG2[0])), (&(RCSC_REAL[0])),
         (&(RCSC_IMAG[0])));

  /* MATLAB Function: '<S1>/DeltaY' */
  DeltaY((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),
         (&(RCSC_IMAG2[0])));
}

/* Model step function */
void rtwdemo_reusable_csc_step(void)
{
  int32_T i;

  /* ComplexToRealImag: '<Root>/Complex to Real-Imag' incorporates:
   *  Inport: '<Root>/ComplexData'
   */
  for (i = 0; i < 1048576; i++) {
    RCSC_REAL[i] = rtU.ComplexData[i].re;
    RCSC_IMAG[i] = rtU.ComplexData[i].im;
  }

  /* End of ComplexToRealImag: '<Root>/Complex to Real-Imag' */

  /* MATLAB Function: '<Root>/Downsample' */
  Downsample((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),
             (&(RCSC_IMAG2[0])));

  /* Outputs for Atomic SubSystem: '<Root>/DeltaSubsystem' */
  DeltaSubsystem();

  /* End of Outputs for SubSystem: '<Root>/DeltaSubsystem' */

  /* Outport: '<Root>/Out1' incorporates:
   *  RealImagToComplex: '<Root>/Real-Imag to Complex'
   */
  for (i = 0; i < 261121; i++) {
    rtY.Out1[i].re = RCSC_REAL2[i];
    rtY.Out1[i].im = RCSC_IMAG2[i];
  }

  /* End of Outport: '<Root>/Out1' */
}

Переменные RCSC_REAL и RCSC_IMAG содержат выходные параметры блока Complex to Real-Image и DeltaX. Эти переменные содержат входные параметры к блоку DeltaY. Переменные RCSC_REAL2 и RCSC_IMAG2 содержат выходные параметры Downsample и DeltaY. Эти переменные содержат входные параметры к блоку DeltaX. Путем чередования буферов таким образом, вы устраняете глобальные переменные в сгенерированном коде.

Чтобы удалить объекты сигнала из сигнальных линий и регенерировать код, в Окне Команды MATLAB, вводят эти команды:

portHandles = get_param(...
    'rtwdemo_reusable_csc/Complex to Real-Imag','portHandles');
set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');
set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

portHandles = get_param(...
    'rtwdemo_reusable_csc/Downsample','portHandles');
set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');
set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

portHandles = get_param(...
    'rtwdemo_reusable_csc/DeltaSubsystem/DeltaX','portHandles');
set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');
set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

portHandles = get_param(...
    'rtwdemo_reusable_csc/DeltaSubsystem/DeltaY','portHandles');
set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');
set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

rtwbuild(model);
### Starting build procedure for model: rtwdemo_reusable_csc
### Successful completion of build procedure for model: rtwdemo_reusable_csc

Файл rtwdemo_reusable_csc.c теперь содержит этот код.

cfile = fullfile(cgDir,...
    'rtwdemo_reusable_csc_ert_rtw','rtwdemo_reusable_csc.c');
rtwdemodbtype(cfile,...
    '/* Output and update for atomic system: ''<Root>/DeltaSubsystem'' */',...
    '/* Output and update for atomic system: ''<Root>/Downsample'' */',1,0);
rtwdemodbtype(cfile,...
    '/* Model step function */','/* Model initialize function */',1,0);
/* Output and update for atomic system: '<Root>/DeltaSubsystem' */
static void DeltaSubsystem(void)
{
  /* MATLAB Function: '<S1>/DeltaX' */
  DeltaX(rtDWork.z2, rtDWork.z1, rtDWork.z1_m, rtDWork.z2_c);

  /* MATLAB Function: '<S1>/DeltaY' */
  DeltaY(rtDWork.z1_m, rtDWork.z2_c, &rtDWork.z1[0], &rtDWork.z2[0]);
}

/* Model step function */
void rtwdemo_reusable_csc_step(void)
{
  int32_T i;

  /* ComplexToRealImag: '<Root>/Complex to Real-Imag' incorporates:
   *  Inport: '<Root>/ComplexData'
   */
  for (i = 0; i < 1048576; i++) {
    rtDWork.RCSC_REAL[i] = rtU.ComplexData[i].re;
    rtDWork.RCSC_IMAG[i] = rtU.ComplexData[i].im;
  }

  /* End of ComplexToRealImag: '<Root>/Complex to Real-Imag' */

  /* MATLAB Function: '<Root>/Downsample' */
  Downsample(rtDWork.RCSC_REAL, rtDWork.RCSC_IMAG, rtDWork.z2, rtDWork.z1);

  /* Outputs for Atomic SubSystem: '<Root>/DeltaSubsystem' */
  DeltaSubsystem();

  /* End of Outputs for SubSystem: '<Root>/DeltaSubsystem' */

  /* Outport: '<Root>/Out1' incorporates:
   *  RealImagToComplex: '<Root>/Real-Imag to Complex'
   */
  for (i = 0; i < 261121; i++) {
    rtY.Out1[i].re = rtDWork.z1[i];
    rtY.Out1[i].im = rtDWork.z2[i];
  }

  /* End of Outport: '<Root>/Out1' */
}

Сгенерированный код содержит две дополнительных глобальных переменные для содержания вводов и выводов блока.

Примечание: можно задать буферное повторное использование на сигналах, что генератор кода не может реализовать. Для тех случаев используйте две новой диагностики, чтобы задать тип сообщения, который отображает модель. В диалоговом окне Configuration Parameters эта диагностика, Обнаруживают неснова использованные пользовательские классы памяти и Обнаруживают неоднозначные пользовательские окончательные значения класса памяти.

bdclose(model)
rtwdemoclean;
cd(currentDir)

Буферное повторное использование для блоков единичной задержки и задержки

Снова использовать сигнал блока Unit Delay или Delay:

  1. Используйте ту же допускающую повторное использование пользовательскую спецификацию класса памяти для пары входа и утвердите аргументы или пару вывода и утвердите аргументы блока Unit Delay или блока Delay.

  2. В Model Data Editor выберите вкладку Штатов и из представления Change выпадающий список, выберите Code.

  3. Используйте столбец Имени, чтобы определить имя целевых состояний блока Единичной задержки или Задержки. Задайте имя объекта сигнала, который вы хотите снова использовать.

  4. Для каждого состояния установите флажок в столбце Твердости.

Для блоков Задержки необходимо установить параметр длины Задержки на 1 и Начальное условие> Источник к Dialog. Чтобы получить доступ к этим параметрам, в модели, открывают Property Inspector (Представление> Property Inspector) и кликают по блоку в модели.

Ограничения для корневых сигналов Inport и выходного порта

Эти ограничения применяются к модели, в которой вы задаете буферное повторное использование для пары корневого импорта и сигналов выходного порта:

  • Выходные порты не могут быть условным выражением.

  • Если генератор кода не может снова использовать тот же буфер в топ-модели, сгенерированный код содержит дополнительные буферы. Если топ-модель является эталонной моделью, генератор кода сообщает об ошибке. Чтобы разрешить ошибку, удалите спецификацию Simulink.signal из сигнала, который соединяется с портом выходного порта.

  • Когда вы запускаете исполняемый файл, который производит генератор кода, и вы снова используете пару корневого импорта и сигналов выходного порта, когда корневое входное значение является нулем, корневое выходное значение должно также быть нулем. Если выходное значение является ненулевым, и вы снова используете сигналы, то результаты симуляции могут отличаться от результатов, к которым приводит исполняемый файл.

  • Может быть симуляция по сравнению с несоответствием генерации кода, когда вы присваиваете тот же Допускающий повторное использование пользовательский класс памяти паре корневого импорта и корневых сигналов выходного порта. Это несоответствие происходит, когда блок Assignment управляет блоком Root Outport, и блок Assignment не присваивает значение каждому элементу выходного сигнала, потому что порт Y0 блока Assignment не активен. Это изображение показывает модель, в которой происходит несоответствие:

Во время симуляции незаписанные выходные значения блока Assignment являются нулем. Во время генерации кода незаписанные выходные значения совпадают с входом.

Ограничения для модели

Эти ограничения применяются к модели, в которой вы задаете буферное повторное использование для сигналов:

  • Сигналы, что вы задаете для повторного использования, должны иметь уровни выборки и совпадающие типы данных.

  • Для заданного пользователями буферного повторного использования блоки, которые изменяют сигнал, заданный для повторного использования, должны выполниться перед блоками, которые используют исходное значение сигналов. Иногда генератор кода должен изменить порядок блочной операции так, чтобы буферное повторное использование могло произойти. Для моделей, в которых генератор кода не может переупорядочить блочные операции, не происходит буферное повторное использование.

  • Для моделей, в которых генератор кода переупорядочивает блочные операции так, чтобы повторное использование Simulink.Signal могло произойти, можно наблюдать различие в отсортированном порядке. В окне модели выберите Display> Blocks> Sorted Execution Order. Чтобы отобразить отсортированный порядок выполнения во время симуляции, выберите Simulation> Update Diagram. Чтобы отобразить порядок выполнения в сгенерированном коде, выберите Code> C/C ++ Code> Build Model.

Похожие темы