Задайте буферное повторное использование при помощи 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. В галерее Apps, под Генерацией кода, нажимают Embedded Coder. Вкладка C Code открывается.

  2. Кликните по Model Data Editor.

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

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

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

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

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

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

  9. В модели перейдите в DeltaSubsystem подсистема.

  10. Выберите 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 и блоков задержки

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Для моделей, в которых генератор кода переупорядочивает блочные операции так, чтобы Simulink.Signal повторное использование может произойти, можно наблюдать различие в отсортированном порядке. На вкладке Debug, в разделе Diagnostics выбирают Information Overlays выпадающая стрела. В разделе Blocks диалогового окна выберите Execution Order. Чтобы отобразить отсортированный порядок выполнения в процессе моделирования, на вкладке Modeling, выбирают Update Model. Чтобы отобразить порядок выполнения в сгенерированном коде, на вкладке C Code, выбирают Build Model.

Похожие темы