使用跨版本工作流集成生成的代码
此示例说明如何通过创建跨版本软件在环 (SIL) 模块并将该模块整合到集成模型中来重用以前生成的代码。有关工作流的详细信息,请参阅 Cross-Release Code Integration。
从模型中生成代码
在跨版本代码集成工作流中,您可以从以前生成的代码创建一个软件在环 (SIL) 或处理器在环 (PIL) 模块。
此示例使用从当前版本中生成的代码。
model = 'CrossReleaseCounter'; close_system(model,0) load_system(model) set_param(model, 'SimulationCommand', 'update'); open_system(model) slbuild(model);
### Starting build procedure for: CrossReleaseCounter ### Successful completion of code generation for: CrossReleaseCounter Build Summary Top model targets built: Model Action Rebuild Reason ======================================================================================== CrossReleaseCounter Code generated. Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 9.4369s
标识包含生成代码的编译文件夹。
buildFolder = RTW.getBuildDir(model).BuildDirectory;
标识包含与生成的代码相关联的共享实用工具代码的文件夹。
previousSharedCodeFolder = RTW.getBuildDir(model).SharedUtilsTgtDir;
要重用以前版本中生成的代码,请执行以下操作:
在仿真选项卡的文件部分中,选择保存 > 以前的版本。
在另存为类型字段中,指定版本和模型类型。
点击保存。
使用以前的版本打开保存的模型,然后生成代码。
将
buildFolder
的值设置为上一版本中生成的代码的位置。将
previousSharedCodeFolder
的值设置为上一版本中生成的共享实用工具的位置。
管理共享代码
将生成的共享源代码文件添加到集成模型使用的存储库文件夹中。
sharedCodeRepo = 'SharedCodeRepo'; mkdir(sharedCodeRepo); sharedCodeUpdate(previousSharedCodeFolder, sharedCodeRepo, 'Interactive', false);
The following files will be copied from slprj/ert/_sharedutils to SharedCodeRepo/R2024a: rtwtypes.h Files copied from slprj/ert/_sharedutils to SharedCodeRepo/R2024a.
导入代码
加载集成模型。
integrationModel = 'CrossReleaseIntegration';
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: CrossReleaseCounter_R2024a ### Starting build process for SIL block: CrossReleaseCounter_R2024a
将跨版本 SIL 模块合并到集成模型中
要将集成模型中的模块替换为跨版本模块,请使用 pil_block_replace
。此函数保留模块大小、信号线连接和优先级。
srcBlock = getfullname(blockHandle); dstBlock = [integrationModel, '/', 'Counter']; pil_block_replace(srcBlock, dstBlock) open_system(integrationModel)
Successfully swapped the following blocks: untitled/CrossReleaseCounter_R2024a_sil CrossReleaseIntegration/Counter
集成模型的仿真
运行集成模型的仿真。
sim(integrationModel)
### Preparing to start SIL block simulation: <a href="matlab: targets_hyperlink_manager('run',1);">CrossReleaseIntegration/Counter</a> ... ### Starting SIL simulation for component: CrossReleaseCounter_R2024a_sil ### Application stopped ### Stopping SIL simulation for component: CrossReleaseCounter_R2024a_sil
调整参数
跨版本 SIL 模块的源模型引用两个可调参数,这些参数由基础工作区中的 Simulink.Parameter 对象控制。使用这些参数修改 SIL 仿真的行为。
countUpper.Value = 30; countLower.Value = 20; yout_retuned = sim(integrationModel, 'ReturnWorkspaceOutputs', 'on');
### Preparing to start SIL block simulation: <a href="matlab: targets_hyperlink_manager('run',1);">CrossReleaseIntegration/Counter</a> ... ### Starting SIL simulation for component: CrossReleaseCounter_R2024a_sil ### Application stopped ### Stopping SIL simulation for component: CrossReleaseCounter_R2024a_sil
在集成模型中配置信号的存储类
配置:
集成模型中的信号名称,以匹配在导入代码中使用的名称。
补充存储类。
在本示例中,ticks
输入和 count
输出是通过导入的代码中的 ImportedExtern
存储类来实现的。如果连接到集成模型中跨版本模块的输入和输出端口的信号的存储类为 ExportedGlobal
,则集成模型必须提供变量的定义。
如果信号名称不匹配,则集成模型将生成附加代码,以在由集成模型实现的信号和由导入的代码实现的信号之间复制数据。
hLines = get_param(dstBlock, 'LineHandles'); % Use the code mappings API to configure the storage class on the signals. cm = coder.mapping.api.get(integrationModel); ticksPortHandle = get(hLines.Inport(1), 'SrcPortHandle'); set(ticksPortHandle, 'Name', 'ticks'); addSignal(cm, ticksPortHandle); setSignal(cm, ticksPortHandle, 'StorageClass', 'ExportedGlobal'); countPortHandle = get(hLines.Outport(1), 'SrcPortHandle'); set(countPortHandle, 'Name', 'count'); addSignal(cm, countPortHandle); setSignal(cm, countPortHandle, '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);
生成代码。
slbuild(integrationModel);
### Starting build procedure for: CrossReleaseIntegration ### Successful completion of code generation for: CrossReleaseIntegration Build Summary Top model targets built: Model Action Rebuild Reason ============================================================================================ CrossReleaseIntegration Code generated. Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 12.391s
检查对导入代码的调用
要检查集成模型代码中的跨版本模块代码,请使用 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: CrossReleaseIntegration ### Successful completion of build procedure for: CrossReleaseIntegration Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================================================== CrossReleaseIntegration Code generated and compiled. S-function CrossReleaseCounter_R2024a_sil does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 10.406s ### Preparing to start SIL simulation ... Building with 'gcc'. MEX completed successfully. ### Updating code generation report with SIL files ... ### Starting SIL simulation for component: CrossReleaseIntegration ### Application stopped ### Stopping SIL simulation for component: CrossReleaseIntegration
比较仿真输出
比较以下两种仿真输出:在 SIL 模式下只运行导入代码的仿真输出,以及在 SIL 模式下作为顶层模型运行的集成模型的仿真输出。
max(abs(yout_SIL.yout{1}.Values.Data - yout_retuned.yout{1}.Values.Data))
ans = uint8 0