Если ваша модель имеет оптимальные установки параметров для удаления копий данных, вы можете смочь удалить дополнительные копии данных при помощи Simulink.Signal
объекты задать буферное повторное использование. После изучения сгенерированного кода и Статического Метрического Отчета Кода и идентификации областей, где вы думаете, буферное повторное использование возможно, вы задаете объекты сигнала на сигнальных линиях.
Можно задать буферное повторное использование на сигналах, которые включают пару корневого импорта и сигналов выходного порта. Можно также задать буферное повторное использование на только паре корневого импорта и сигналов выходного порта. Эта оптимизация уменьшает ROM и потребление RAM, потому что существуют менее глобальные переменные и копии данных в сгенерированном коде. Скорость выполнения кода также увеличивается.
Модель rtwdemo_reusable_csc содержит подсистему одноразового использования DeltaSubsystem
и блок MATLAB function Downsample
. DeltaSubsystem
содержит блоки MATLAB function DeltaX
и DeltaY
.
model ='rtwdemo_reusable_csc';
open_system(model);
В галерее Apps, под Генерацией кода, нажимают Embedded Coder. Вкладка C Code открывается.
Кликните по Model Data Editor.
В Model Data Editor, на вкладке Signals, от представления Change выпадающий список, выбирают Code
.
Нажмите кнопку дополнительной информации Show/refresh. Теперь Model Data Editor показывает информацию о переменных и объектах в рабочих областях, таких как базовое рабочее пространство.
Рядом с полем содержимого Фильтра активируйте Фильтр с помощью кнопки выбора.
В модели выберите RCSC_REAL
сигнальная линия. Model Data Editor показывает две строки: Тот, который представляет сигнальную линию и ту, которая представляет Simulink.Signal
объект в базовом рабочем пространстве.
Для строки, которая представляет сигнальную линию, смотрите столбец Твердости. Флажок устанавливается, что значит твердость сигнальной линии для Simulink.Signal
объект, получая настройки генерации кода от того объекта.
Для строки, которая представляет объект сигнала, смотрите столбец Класса памяти. Объект сигнала использует класс памяти Reusable
, что означает, что объект появляется в сгенерированном коде как глобальная переменная под названием RCSC_REAL
.
В модели перейдите в DeltaSubsystem
подсистема.
Выберите 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:
Используйте ту же допускающую повторное использование спецификацию класса памяти в паре входа и утвердите аргументы или пару выхода и утвердите аргументы блока Unit Delay или блока Delay.
В Model Data Editor выберите вкладку Штатов и из представления Change выпадающий список, выберите Code
.
Используйте столбец Имени, чтобы определить имя целевого Unit Delay или состояний блока Задержки. Задайте имя объекта сигнала, который вы хотите снова использовать.
Для каждого состояния установите флажок в столбце Твердости.
Для блоков Задержки необходимо установить параметр длины Задержки на 1
и Начальное условие> Источник к Dialog
. Чтобы получить доступ к этим параметрам, в модели, открывают Property Inspector и кликают по блоку в модели.
Эти ограничения применяются к модели, в которой вы задаете буферное повторное использование для пары корневого импорта и сигналов выходного порта:
Выходные порты не могут быть условным выражением.
Если генератор кода не может снова использовать тот же буфер в топ-модели, сгенерированный код содержит дополнительные буферы. Если топ-модель является эталонной моделью, генератор кода сообщает об ошибке. Чтобы разрешить ошибку, удалите спецификацию 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.