Main Content

本页采用了机器翻译。点击此处可查看英文原文。

验证组件的代码生成

关于示例模型

此示例使用 slvnvdemo_powerwindow模型来展示如何在包含该组件的模型上下文中验证该组件。在完成此示例的过程中,您将使用 Simulink® Design Verifier™ 组件验证函数来创建测试用例并测量引用模型的覆盖率。此外,您可以使用代码生成验证 (CGV) API 在仿真模式和软件在环 (SIL) 模式下执行参考模型。

注意

您必须拥有以下产品许可证才能运行此示例:

  • Stateflow®

  • Embedded Coder®

  • Simulink Coder™

您验证的组件是名为 controlModel模块。该组件位于 slvnvdemo_powerwindow模型顶层的 power_window_control_system 子系统内。power_window_control_system子系统如下所示。

control Model模块引用了slvnvdemo_powerwindow_controller模型。

引用的模型包含一个Stateflow图表control,它实现了电动车窗控制器的逻辑。

准备组件进行验证

为了验证引用的模型slvnvdemo_powerwindow_controller,创建一个包含仿真工厂模型中的控制器的输入信号的框架模型:

  1. 打开slvnvdemo_powerwindow示例模型和引用的模型:

    openExample('sldv/CreatingAndExecutingTestCasesExample',...
    'supportingFile','slvnvdemo_powerwindow');
    open_system('slvnvdemo_powerwindow_controller');
    
  2. 打开示例模型中的power_window_control_system子系统。

    power_window_control_system 子系统中名为 controlModel模块引用您在此示例中验证的组件 slvnvdemo_powerwindow_controller

  3. 仿真引用slvnvdemo_powerwindow_controller模型的Model模块并将输入信号记录到Model模块:

    loggedSignalsPlant = sldvlogsignals( ...
    	'slvnvdemo_powerwindow/power_window_control_system/control');

    sldvlogsignals 将记录的信号存储在 loggedSignalsPlant 中。

  4. 使用记录的信号生成框架模型:

    harnessModelFilePath = sldvmakeharness( ...
    	'slvnvdemo_powerwindow_controller', loggedSignalsPlant);
    

    sldvmakeharness 创建并打开一个名为 slvnvdemo_powerwindow_controller_harness 的框架模型。Signal Editor模块包含一个包含记录信号的测试用例。

    有关框架模型的更多信息,请参阅 管理Simulink Design Verifier框架模型

  5. 为了在此示例后面使用,请保存框架模型的名称:

    [~, harnessModel] = fileparts(harnessModelFilePath);
  6. 保持所有窗口打开以便进行此示例的下一部分。

接下来,您将记录 slvnvdemo_powerwindow_controller模型的覆盖率。

记录组件的覆盖范围

模型覆盖率衡量测试用例测试模型的彻底程度,以及测试用例执行的路径的百分比。记录slvnvdemo_powerwindow_controller模型的覆盖率:

  1. 创建一个默认选项对象,这是 sldvruntest 函数所需要的:

    runOpts = sldvruntestopts;
  2. 指定要仿真的模型,并记录覆盖率:

    runOpts.coverageEnabled = true;
  3. 仿真参考模型并记录覆盖率:

    [~, covDataFromLoggedSignals] = sldvruntest( ...
    	'slvnvdemo_powerwindow_controller', loggedSignalsPlant, runOpts);
  4. 显示 HTML覆盖率报告:

    cvhtml('Coverage with Test Cases', covDataFromLoggedSignals);

    slvnvdemo_powerwindow_controller模型实现了:

    • 决策覆盖率:40%

    • 条件覆盖率:35%

    • MCDC覆盖率:10%

    有关决策覆盖率、条件覆盖率和 MCDC覆盖率的更多信息,请参阅 模型覆盖的类型 (Simulink Coverage)

由于您没有实现 slvnvdemo_powerwindow_controller模型的 100%覆盖率,接下来,您将分析该模型以记录额外的覆盖率并创建额外的测试用例。

使用Simulink Design Verifier软件记录附加覆盖范围

您可以使用Simulink Design Verifier来分析slvnvdemo_powerwindow_controller模型并收集覆盖率。您可以指定分析忽略任何先前满足的目标并记录额外的覆盖率。

记录模型的额外覆盖率:

  1. 将您记录的信号的覆盖率数据保存在文件中:

    cvsave('existingCovFromLoggedSignal', covDataFromLoggedSignals);
  2. 为分析创建一个默认选项对象:

    opts = sldvoptions;
  3. 指定分析生成测试用例来记录决策、条件和修正条件/决策覆盖率:

    opts.ModelCoverageObjectives = 'MCDC';
  4. 指定分析忽略将信号记录到 Model模块时满足的目标:

    opts.IgnoreCovSatisfied = 'on';
  5. 指定包含满足的目标数据的文件的名称:

    opts.CoverageDataFile = 'existingCovFromLoggedSignal.cvt';
  6. 指定分析创建满足以下几个目标的长测试用例:

    opts.TestSuiteOptimization = 'LongTestcases';

    创建较少数量的测试用例(每个测试用例满足多个测试目标)可以在下一部分执行生成的代码时节省时间。

  7. 指定使用 Model模块创建引用组件的框架模型:

    opts.saveHarnessModel = 'on';
    opts.ModelReferenceHarness = 'on';

    您根据 准备组件进行验证 中记录的信号创建的框架模型使用引用 slvnvdemo_powerwindow_controller模型的Model模块。分析创建的框架模型还必须使用引用 slvnvdemo_powerwindow_controllerModel模块。您可以将测试用例数据附加到第一个框架模型,从而创建单个测试套件。

  8. 使用Simulink Design Verifier分析模型:

    [status, fileNames] = sldvrun('slvnvdemo_powerwindow_controller', ...
    	opts, true);

    分析创建并打开了框架模型slvnvdemo_powerwindow_controller_harnessSignal Editor模块包含一个满足 74 个测试目标的长测试用例。

    您可以将此测试用例与您在准备组件进行验证中创建的测试用例相结合,以记录slvnvdemo_powerwindow_controller模型的额外覆盖率。

  9. 保存新的框架模型的名称并打开:

    [~, newHarnessModel] = fileparts(fileNames.HarnessModel);
    open_system(newHarnessModel); 

接下来,您将结合这两个框架模型来创建一个测试套件。

结合框架模型

在执行下列操作时,您创建了两个框架模型:

  • 将信号记录到引用slvnvdemo_powerwindow_controller模型的控制Model模块。

  • 分析了slvnvdemo_powerwindow_controller模型。

如果将两种框架模型中的测试用例结合起来,则可以记录覆盖率,从而使其更接近实现 100%覆盖率:

  1. 通过将最新的测试用例附加到已记录信号的测试用例来组合框架模型:

    sldvmergeharness(harnessModel, newHarnessModel);

    slvnvdemo_powerwindow_controller_harness模型中的 Signal Editor模块现在包含两个测试用例。

  2. 将信号记录到框架模型:

    loggedSignalsMergedHarness = sldvlogsignals(harnessModel);
  3. 使用组合测试用例来记录slvnvdemo_powerwindow_controller_harness模型的覆盖率。首先,配置sldvruntest的选项对象:

    runOpts = sldvruntestopts;
    runOpts.coverageEnabled = true;
  4. 仿真模型并记录和显示覆盖率数据:

    [~, covDataFromMergedSignals] = sldvruntest( ...
    	'slvnvdemo_powerwindow_controller', loggedSignalsMergedHarness, ...
    	runOpts);
    cvhtml('Coverage with Merged Test Cases', covDataFromMergedSignals);

    slvnvdemo_powerwindow_controller模型现在实现:

    • 决策覆盖率:100%

    • 条件覆盖率:80%

    • MCDC覆盖率:60%

在仿真模式下执行组件

要验证模型生成的代码是否产生与仿真模型相同的结果,请使用代码生成验证 (CGV) API 方法。

注意

要以不同的执行模式执行模型,请使用 CGV API 来验证结果的数值等效性。有关 CGV API 的更多信息,请参阅 以编程方式进行代码生成验证 (Embedded Coder)

当您执行此过程时,仿真将使用两个测试用例编译并执行模型代码。

  1. sldvruncgvtest 创建一个默认选项对象:

    runcgvopts = sldvruntestopts('cgv');
  2. 指定以仿真模式执行模型:

    runcgvopts.cgvConn = 'sim';
  3. 使用两个测试用例和 runcgvopts 对象执行 slvnv_powerwindow_controller模型:

    cgvSim = sldvruncgvtest('slvnvdemo_powerwindow_controller', ...
    	loggedSignalsMergedHarness, runcgvopts);

    这些步骤将结果保存在工作区变量 cgvSim 中。

接下来,您将在软件在环 (SIL) 模式下使用相同的测试用例执行相同的模型,并比较两次仿真的结果。

有关正常仿真模式的更多信息,请参阅 什么是 SIL 和 PIL 仿真? (Embedded Coder)

在软件在环 (SIL) 模式下执行组件

当您在软件在环 (SIL) 模式下执行模型时,仿真会在主机上编译并执行生成的代码。

在本节中,您将在 SIL 模式下执行 slvnvdemo_powerwindow_controller模型,并将结果与上一节在仿真模式下执行模型的结果进行比较。

  1. 指定以SIL模式执行模型:

    runcgvopts.cgvConn = 'sil';
  2. 使用两个测试用例和 runcgvopts 对象执行 slvnv_powerwindow_controller模型:

    cgvSil = sldvruncgvtest('slvnvdemo_powerwindow_controller', ...
    	loggedSignalsMergedHarness, runcgvopts);

    工作区变量cgvSil包含SIL模式执行的结果。

  3. cgvSil中的结果与仿真模式执行创建的cgvSim中的结果进行比较。使用 compare (Embedded Coder) 方法比较两次仿真的结果:

    for i=1:length(loggedSignalsMergedHarness.TestCases)
        simout = cgvSim.getOutputData(i);
        silout = cgvSil.getOutputData(i);
        [matchNames, ~, mismatchNames, ~ ] = ...
    			cgv.CGV.compare(simout, silout);
    end
  4. 在 MATLAB® 命令窗口中显示比较结果:

    fprintf(['\nTest Case(%d):%d Signals match, %d Signals mismatch\r'],...
    	i, length(matchNames), length(mismatchNames));
    

    正如预期的那样,两次仿真的结果相匹配。

有关软件在环 (SIL) 仿真的更多信息,请参阅 什么是 SIL 和 PIL 仿真? (Embedded Coder)