用SIL和PIL模拟测试生成的代码
通过使用软件在循环(SIL)和处理器在循环(PIL)模拟,测试模型组件和从组件生成的生产代码之间的数值等价性。
使用SIL模拟,您可以在开发计算机上测试源代码。使用PIL模拟,您可以通过在真正的目标硬件或指令集模拟器上运行目标代码来测试您打算在生产中部署的已编译的目标代码。为了确定模型组件和生成的代码是否在数值上等价,将SIL和PIL的结果与正常模式的结果进行比较。
有三种运行SIL和PIL模拟的方法。您可以使用从子系统创建的顶级模型、模型块,或者SIL和PIL块。看到选择SIL或PIL方法.
PIL的目标连通性配置
在运行PIL模拟之前,必须配置目标连通性。目标连通性配置使PIL模拟能够:
构建目标应用程序。
下载、启动和停止目标上的应用程序。
支持Simulink和目标之间的通信。
要生成目标连接性配置,可以使用提供的目标连接性API。详情请参见为Simulink创建PIL目标连通性配置.
对于支持的硬件,可以使用目标支持包。详情请参见嵌入式编码器支持的硬件.
用顶层模型进行SIL或PIL仿真
通过运行顶级模型SIL或PIL模拟来测试生成的模型代码。用这种方法:
您可以测试从顶级模型生成的代码,它使用独立代码接口。
您可以配置模型以从MATLAB工作区加载测试向量或刺激输入。
您可以轻松地在正常、SIL和PIL模拟模式之间切换顶级模型。
打开一个简单的台面模型。
模型=“SILTopModel”;close_system(模型中,0)open_system(模型)
要专注于数值等价测试,请关闭:
模型覆盖
代码覆盖率
执行时间分析
set_param (gcs,“RecordCoverage”,“关闭”);coveragessets = get_param(model,“CodeCoverageSettings”);coverageSettings。CoverageTool =“没有”;set_param(模型,“CodeCoverageSettings”, coverageSettings);set_param(模型,“CodeExecutionProfiling”,“关闭”);
配置输入刺激数据。
[ticks_to_count, reset, counter_mode, count_enable] =...SILTopModelData (T);
在模型中配置日志选项。
set_param(模型,“LoadExternalInput”,“上”);set_param(模型,“ExternalInput”,'ticks_to_count, reset, counter_mode, count_enable');set_param(模型,“SignalLogging”,“上”);set_param(模型,“SignalLoggingName”,“logsOut”);set_param(模型,“SaveOutput”,“上”)
运行正常模式模拟。
set_param(模型,“SimulationMode”,“正常”sim_output = sim(model,10);youout_normal = [sim_output. youout .signals(1). sim_normal = [sim_output. youout .signals]。值sim_output.yout.signals (2) . values);
运行一个顶层模型SIL模拟。
set_param(模型,“SimulationMode”,“Software-in-the-Loop (SIL)”sim_output = sim(model,10);youout_sil = [sim_output. youout .signals(1)。值sim_output.yout.signals (2) . values);
# # #开始构建过程:SILTopModel # # #成功完成构建过程:SILTopModel模型建立目标:总结构建模型重建行动的理由 ============================================================================================= SILTopModel代码生成和编译。代码生成信息文件不存在。构建1个模型(0个模型已经更新)构建持续时间:0h 0m 8.7602s ###准备开始SIL模拟…用'gcc'构建。MEX成功完成。正在用SIL文件更新代码生成报告…###停止组件SILTopModel的SIL模拟
除非存在此模型的最新代码,否则将生成并编译新代码。生成的代码作为单独的进程在计算机上运行。
绘制和比较常规和SIL模拟的结果。观察结果是否匹配。
Fig1 =图;Subplot (3,1,1), plot(youout_normal), title(“正常模拟的计数器输出”) subplot(3,1,2), plot(youout_sil), title(“SIL模拟的计数器输出”) subplot(3,1,3), plot(youout_normal - youout_sil),...标题(“正常和SIL的区别”);
清理。
close_system(模型中,0);如果ishandle(图一),关闭(图一),结束清晰的图一simResults = {“yout_sil”,“yout_normal”,“模型”,“T”,...“ticks_to_count”,“重置”};保存([模型“_results”), simResults {:});明确(simResults {:},“simResults”)
用模型块进行SIL或PIL仿真
通过使用在SIL模式下运行model块的测试工具模型来测试生成的模型代码。用这种方法:
您可以测试从顶级模型或引用模型生成的代码。来自顶层模型的代码使用独立代码接口。来自引用模型的代码使用模型引用代码接口。有关更多信息,请参见SIL和PIL的代码接口.
您可以使用测试工具模型或系统模型来提供测试向量或刺激输入。
您可以轻松地在正常、SIL和PIL模拟模式之间切换Model块。
打开一个示例模型,其中有两个模型块引用相同的模型。在模拟中,您以SIL模式运行一个Model块,而以普通模式运行另一个Model块。
模型=“SILModelBlock”;open_system(模型);
关闭:
代码覆盖率
执行时间分析
coveragessets = get_param(model,“CodeCoverageSettings”);coverageSettings。CoverageTool =“没有”;set_param(模型,“CodeCoverageSettings”, coverageSettings);open_system (“SILModelBlock”) set_param (“SILModelBlock”,“CodeExecutionProfiling”,“关闭”);open_system (“SILCounter”) set_param (“SILCounter”,“CodeExecutionProfiling”,“关闭”);currentFolder = pwd;save_system (“SILCounter”fullfile (currentFolder“SILCounter.slx”))
为模型配置状态日志记录。
set_param (“SILCounter”,“SaveFormat”,“数据集”);save_system (“SILCounter”fullfile (currentFolder“SILCounter.slx”) set_param(模型,“SaveFormat”,“数据集”);set_param(模型,“SaveState”,“上”);set_param(模型,“StateSaveName”,“xout”);
测试顶级模型代码
对于SIL模式下的Model块,指定顶级模型代码的生成,它使用独立代码接口。
set_param([模型' / CounterA '],“CodeInterface”,“高级模式”);
运行测试线束模型的模拟。
Out = sim(模型,20);
# # #开始构建过程:SILCounter # # #成功完成构建过程:SILCounter模型建立目标:总结构建模型重建行动的理由 ============================================================================================ SILCounter代码生成和编译。代码生成信息文件不存在。构建1个模型(0个模型已经更新)构建持续时间:0h 0m 8.1011s ###准备开始SIL模拟…用'gcc'构建。MEX成功完成。正在用SIL文件更新代码生成报告…###启动组件SILCounter的SIL模拟###应用程序已停止###停止组件SILCounter的SIL模拟
SIL模式下的模型块在计算机上作为一个单独的进程运行。在工作文件夹中,您将看到为引用的模型生成独立代码,除非存在从以前的构建生成的代码。
比较模型块在正常和SIL模式下的行为。结果一致。
yout = out.logsOut;youout_sil = you .get(“counterA”) .Values.Data;youout_normal = you .get(“counterB”) .Values.Data;Fig1 =图;Subplot (3,1,1), plot(youout_normal), title(“正常模拟的计数器输出”)次要情节(3、1、2),...情节(yout_sil)、标题(“模型块SIL(顶模型)仿真的计数器输出”) subplot(3,1,3), plot(youout_normal - youout_sil),...标题(“正常和SIL的区别”);
比较来自普通模式和SIL模式模拟的Model块的日志状态。
Xout = out.xout;xout_sil = xout{1}.Values.Data;xout_normal = xout{2}.Values.Data;Fig1 =图;Subplot (3,1,1), plot(xout_sil), title(“正常模拟的状态记录”)次要情节(3、1、2),...情节(xout_normal)、标题(“模型块SIL(顶级模型)模拟的状态记录”) subplot(3,1,3), plot(xout_normal-xout_sil),...标题(“正常和SIL的区别”);
测试模型参考代码
对于SIL模式下的Model块,指定引用模型代码的生成,它使用模型引用代码接口。
set_param([模型' / CounterA '],“CodeInterface”,“模型参考”);
运行测试线束模型的模拟。
Out2 = sim(模型,20);
###开始构建串行模型参考代码。已成功完成:SILCounter构建摘要代码生成目标的构建过程:模型操作重建原因========================================================================生成并编译的SILCounter代码。SILCounter.c不存在。构建1个模型(0个模型已经更新)构建持续时间:0h 0m 6.56557秒###准备开始SIL模拟…用'gcc'构建。MEX成功完成。正在用SIL文件更新代码生成报告…###启动组件SILCounter的SIL模拟###应用程序已停止###停止组件SILCounter的SIL模拟
SIL模式下的模型块在计算机上作为一个单独的进程运行。在工作文件夹中,您会看到生成了模型引用代码,除非存在来自先前构建的代码。
比较模型块在正常和SIL模式下的行为。结果一致。
yout2 = out2.logsOut;Yout2_sil = yout2.get(“counterA”) .Values.Data;Yout2_normal = yout2.get(“counterB”) .Values.Data;Fig1 =图;Subplot (3,1,1), plot(youout2_normal), title(“正常模拟的计数器输出”)次要情节(3、1、2),...情节(yout2_sil)、标题(“模型块SIL(模型参考)仿真的计数器输出”) subplot(3,1,3), plot(yout2_normal-yout2_sil),...标题(“正常和SIL的区别”);
比较来自普通模式和SIL模式模拟的Model块的日志状态。
Xout2 = out.xout;xout2_sil = xout2{1}.Values.Data;xout2_normal = xout2{2}.Values.Data;Fig1 =图;Subplot (3,1,1), plot(xout2_sil), title(“正常模拟的状态记录”)次要情节(3、1、2),...情节(xout2_normal)、标题(“模型块SIL(模型参考)模拟的状态记录”) subplot(3,1,3), plot(xout2_normal-xout2_sil),...标题(“正常和SIL的区别”);
清理。
close_system(模型中,0);如果ishandle(图一),关闭(图一),结束、清晰图一simResults = {“出”,“你”,“yout_sil”,“yout_normal”,...“out2”,“yout2”,“yout2_sil”,“yout2_normal”,...“SilCounterBus”,“T”,“重置”,“ticks_to_count”,“增量”};保存([模型“_results”), simResults {:});明确(simResults {:},“simResults”)
SIL或PIL块模拟
在模拟中使用SIL或PIL块测试生成的子系统代码。用这种方法:
您可以测试从子系统生成的代码,它使用独立代码接口。
您提供一个测试工具或一个系统模型来提供测试向量或刺激输入。
您可以用生成的SIL或PIL块替换原来的子系统。
打开一个简单的模型,它由一个闭环控制算法和一个植物模型组成。控制算法调节装置的输出。
模型=“SILBlock”;close_system(模型中,0)open_system(模型)
运行正常模式模拟
Out = sim(模型,10);youout_normal = out. youout;清晰的出
配置构建过程以创建用于测试的SIL块。
set_param(模型,“CreateSILPILBlock”,“银”);
要在生产硬件上测试行为,请指定一个PIL块。
要创建SIL块,需要为控制算法子系统生成代码。您可以在构建过程的末尾看到SIL块。其输入输出端口与控制算法子系统的输入输出端口相匹配。
close_system (“无题”, 0);slbuild([模型“/控制器”])
正在为:Controller ### ##的构建过程成功完成:Controller ### #正在创建SIL块…用'gcc'构建。MEX成功完成。模型建立目标:总结构建模型重建行动的理由 ============================================================================================ 控制器代码生成和编译。代码生成信息文件不存在。构建1 / 1的模型(0个模型已经更新)构建持续时间:0h 0m 11.426s
或者,您可以右键单击子系统并选择C/ c++ Code > Build This子系统。在打开的对话框中,单击Build。
为了在闭环中对控制器和植物模型进行SIL仿真,用新的SIL块替换原来的控制算法。为了避免丢失原始子系统,不要在此状态下保存模型。
controllerBlock = [model .“/控制器”];blockPosition = get_param(controllerBlock,“位置”);delete_block (controllerBlock);add_block (“untitled /控制器”, (controllerBlock' (SIL) '],...“位置”, blockPosition);close_system (“无题”, 0);清晰的controllerBlockblockPosition
运行SIL模拟。
Out = sim(模型,10);
###准备启动SIL块模拟:SILBlock/Controller(SIL)…###启动组件SILBlock的SIL模拟###应用程序已停止组件SILBlock的SIL模拟
控制算法采用单精度浮点算法。您可以预期SIL和正常模拟之间的差异的数量级接近于单精度数据的机器精度。
为SIL仿真结果定义一个误差容限,该误差容限基于单精度、正常仿真结果的机器精度。
Machine_precision = eps(single(youout_normal));公差= 4 * machine_precision;
比较正常和SIL模拟结果。在第三个图中,模拟之间的差异在定义的容错范围内。
youout_sil = out. youout;Tout = out.tout;Fig1 =图;Subplot (3,1,1), plot(youout_normal), title(“正常模拟的控制器输出”) subplot(3,1,2), plot(youout_sil), title(“用于SIL仿真的控制器输出”) subplot(3,1,3), plot(tout,abs(youout_normal - youout_sil),“g -”吹捧,宽容,的r -),...标题(“正常和SIL的差异和容错”);
清理。
close_system(模型中,0);如果ishandle(图一),关闭(图一),结束清晰的图一simResults = {“出”,“yout_sil”,“yout_normal”,“兜售”,“machine_precision”};保存([模型“_results”), simResults {:});明确(simResults {:},“simResults”)
硬件实现设置
在运行SIL模拟时,必须配置硬件实现设置(例如本机字大小等特征),以允许在开发计算机上进行编译。这些设置可能不同于为生产硬件构建模型时使用的硬件实现设置。为了避免在SIL和PIL模拟之间更改硬件实现设置,可以启用可移植的字大小。有关更多信息,请参见配置硬件实现设置.