В этом примере показано, как снова использовать ранее сгенерированный код путем создания программного обеспечения перекрестного релиза в блоке (SIL) цикла и слияния блока в модели интегрирования. Для получения дополнительной информации о рабочем процессе, смотрите Интеграцию кода перекрестного Релиза.
В рабочем процессе интеграции кода перекрестного релиза вы создаете программное обеспечение в цикле (SIL) или процессоре в блоке (PIL) цикла из кода, который вы ранее сгенерировали.
Этот пример использует сгенерированный код от текущего релиза.
model = 'rtwdemo_crossrelease_counter'; close_system(model,0) load_system(model) set_param(model, 'SimulationCommand', 'update'); open_system(model) rtwbuild(model);
### Starting build procedure for model: rtwdemo_crossrelease_counter ### Successful completion of code generation for model: rtwdemo_crossrelease_counter
Идентифицируйте папку сборки, которая содержит сгенерированный код.
buildFolder = RTW.getBuildDir(model).BuildDirectory;
Идентифицируйте папку, которая содержит код для разделяемых утилит, сопоставленных со сгенерированным кодом.
previousSharedCodeFolder = RTW.getBuildDir(model).SharedUtilsTgtDir;
К сгенерированному коду повторного использования от предыдущего релиза:
На вкладке Simulation, в Разделе файла, выбирают Save> Previous Version.
В Сохранении как поле типа задайте релиз и тип модели.
Нажмите Save.
Используйте предыдущий релиз, чтобы открыть сохраненную модель, и затем сгенерировать код.
Установите значение buildFolder
к местоположению кода, сгенерированного в предыдущем релизе.
Установите значение previousSharedCodeFolder
к местоположению разделяемых утилит, сгенерированных в предыдущем релизе.
Добавьте сгенерированные разделяемые файлы исходного кода в папку репозитория, которая используется моделью интегрирования.
sharedCodeRepo = 'SharedCodeRepo'; mkdir(sharedCodeRepo); sharedCodeUpdate(previousSharedCodeFolder, sharedCodeRepo, 'Interactive', false);
The following files will be copied from slprj/ert/_sharedutils to SharedCodeRepo/R2019b: rtwtypes.h Files copied from slprj/ert/_sharedutils to SharedCodeRepo/R2019b.
Откройте модель интегрирования.
integrationModel = 'rtwdemo_crossrelease_integration';
close_system(integrationModel, 0);
load_system(integrationModel);
Измените конфигурацию модели Simulink так, чтобы она сослалась на существующую разделяемую библиотеку кода.
cs = getActiveConfigSet(integrationModel);
set_param(cs, 'ExistingSharedCode', fullfile(pwd, sharedCodeRepo));
Создайте блок SIL перекрестного релиза.
blockHandle = crossReleaseImport(buildFolder, cs, 'SimulationMode', 'SIL');
### Starting import process for component: rtwdemo_crossrelease_counter_R2019b ### Starting build process for SIL block: rtwdemo_crossrelease_counter_R2019b
Чтобы заменить блок в модели интегрирования с блоком перекрестного релиза, используйте pil_block_replace
. Эта функция сохраняет размер блока, связи линии и приоритет.
srcBlock = getfullname(blockHandle); dstBlock = [integrationModel, '/', 'Counter']; pil_block_replace(srcBlock, dstBlock) open_system(integrationModel)
Successfully swapped the following blocks: untitled/rtwdemo_crossrelease_counter_R2019b_sil rtwdemo_crossrelease_integration/Counter
Запустите симуляцию модели интегрирования.
sim(integrationModel)
### Preparing to start SIL block simulation: rtwdemo_crossrelease_integration/Counter ... ### Starting SIL simulation for component: rtwdemo_crossrelease_counter_R2019b_sil rtw.connectivity.HostLauncher: started executable with host process identifier 32835 rtw.connectivity.HostLauncher: stopped executable with host process identifier 32835 ### Stopping SIL simulation for component: rtwdemo_crossrelease_counter_R2019b_sil
Исходная модель для ссылок блока SIL перекрестного релиза два настраиваемых параметра, которыми управляет Simulink. Объекты параметра в базовом рабочем пространстве. Используйте эти параметры, чтобы изменить поведение SIL симуляции.
countUpper.Value = 30; countLower.Value = 20; yout_retuned = sim(integrationModel, 'ReturnWorkspaceOutputs', 'on');
### Preparing to start SIL block simulation: rtwdemo_crossrelease_integration/Counter ... ### Starting SIL simulation for component: rtwdemo_crossrelease_counter_R2019b_sil rtw.connectivity.HostLauncher: started executable with host process identifier 32953 rtw.connectivity.HostLauncher: stopped executable with host process identifier 32953 ### Stopping SIL simulation for component: rtwdemo_crossrelease_counter_R2019b_sil
Сконфигурируйте:
Имена сигнала в модели интегрирования, чтобы совпадать с именами, используемыми в импортированном коде.
Дополнительные классы памяти.
В этом случае, ticks
введите и count
выход реализован через ImportedExtern
класс памяти в импортированном коде. Если классом памяти для сигналов, соединенных с портами ввода и вывода блока перекрестного релиза в модели интегрирования, является ExportedGlobal
, модель интегрирования должна предоставить определения для переменных.
Если имена сигнала не соответствуют, модель интегрирования генерирует дополнительный код, чтобы скопировать данные между сигналом, реализованным моделью интегрирования и сигналом, реализованным импортированным кодом.
hLines = get_param(dstBlock, 'LineHandles'); set(hLines.Inport(1), 'Name', 'ticks', 'StorageClass', 'ExportedGlobal'); set(hLines.Outport(1), 'Name', 'count', 'StorageClass', 'ExportedGlobal');
Параметры и хранилища данных реализованы через ImportedExtern
класс памяти в импортированном коде. Если вы конфигурируете параметры и хранилища данных, чтобы использовать ExportedGlobal
класс памяти, модель интегрирования должна предоставить определения для переменных.
resetSignal.CoderInfo.StorageClass = 'ExportedGlobal'; countLower.CoderInfo.StorageClass = 'ExportedGlobal'; countUpper.CoderInfo.StorageClass = 'ExportedGlobal';
Если необходимый разделяемый код находится в разделяемом репозитории кода, удалите ранее сгенерированную разделяемую сервисную папку.
if isfolder(RTW.getBuildDir(integrationModel).SharedUtilsTgtDir) rmdir(RTW.getBuildDir(integrationModel).SharedUtilsTgtDir, 's'); end
Удалите осциллограф и соединительную линию, которые не влияют на генерацию кода.
scopeBlock = [integrationModel, '/', 'Scope']; hScopeLines = get_param(scopeBlock, 'LineHandles'); hScopeLine = hScopeLines.Inport(1); assert(strcmp(get(hScopeLine, 'SegmentType'), 'branch')); delete_line(hScopeLine); delete_block(scopeBlock);
Сгенерируйте код.
rtwbuild(integrationModel);
### Starting build procedure for model: rtwdemo_crossrelease_integration ### Successful completion of code generation for model: rtwdemo_crossrelease_integration
Чтобы исследовать блочный код перекрестного релиза в рамках типового кодекса интегрирования, используйте rtwtrace
утилита.
rtwtrace(dstBlock);
Запустите программное обеспечение топ-модели в цикле (SIL) симуляция модели интегрирования. Симуляция запускает код, сгенерированный из модели интегрирования, которая вызывает импортированный код.
Регистрируйте симуляцию выход в рабочей области.
set_param(integrationModel, 'SimulationMode', 'software-in-the-loop (sil)'); yout_SIL = sim(integrationModel, 'ReturnWorkspaceOutputs', 'on'); plot(yout_SIL.yout{1}.Values);
### Starting build procedure for model: rtwdemo_crossrelease_integration ### Successful completion of build procedure for model: rtwdemo_crossrelease_integration ### Preparing to start SIL simulation ... Building with 'gcc'. MEX completed successfully. ### Updating code generation report with SIL files ... ### Starting SIL simulation for component: rtwdemo_crossrelease_integration ### Stopping SIL simulation for component: rtwdemo_crossrelease_integration
Сравните выходные параметры от симуляции, откуда только импортированный код запустился в режиме SIL с выходными параметрами симуляции, куда модель интегрирования запустилась как топ-модель в режиме SIL.
max(abs(yout_SIL.yout{1}.Values.Data - yout_retuned.yout{1}.Values.Data))
ans = uint8 0