Embedded Coder

Collecting Code Coverage Metrics

This example shows how to use either SIL or PIL simulation mode to collect code coverage metrics. To enable code coverage measurement, you must install a supported code coverage tool, for example, BullseyeCoverage or LDRA Testbed. The following screen shot shows a sample code coverage report obtained after running a SIL simulation with code coverage enabled. Note that the annotations are dependent on the code coverage tool you have selected.

In this example, you will learn how to measure model coverage during normal mode simulation and repeat the same simulation in SIL mode to measure code coverage. You can use the hyperlinks in the model coverage and code coverage reports to compare model coverage and code coverage results for part of the model.

To run the model coverage portion this example, you must have Simulink® Verification and Validation™ installed (see the documentation for details).

To run the code coverage portion this example, you must have a supported code coverage tool installed (see the documentation for details).

See also rtwdemo_sil_pil_scriptrtwdemo_sil_pil_script.

Initial Setup

% Make sure the model is freshly opened
model='rtwdemo_sil_topmodel';
close_system(model,0)
open_system(model)

% Remove existing build folders
buildFolder=RTW.getBuildDir(model);
if exist(buildFolder.BuildDirectory,'dir')
    rmdir(buildFolder.BuildDirectory,'s');
end

% Configure model coverage to 'off'. Change this setting to 'on' to
% generate a model coverage report.
set_param(model, 'RecordCoverage','off')
clear covCumulativeData

% Set up the stimulus data
T=0.1; % sample time
[ticks_to_count, reset, counter_mode, count_enable, ...
 counter_mode_values_run1, counter_mode_values_run2, ...
 count_enable_values_run1, count_enable_values_run2] = ...
    rtwdemo_sil_topmodel_data(T);

Run a Simulation in Normal Mode

The model is configured to collect model coverage metrics. Enter the following commands to run a simulation. When the simulation is complete, you should view the model coverage report that is opened automatically. Use the coverage display window to navigate from blocks in the model to the corresponding section of the coverage report.

counter_mode.signals.values = counter_mode_values_run1;
count_enable.signals.values = count_enable_values_run1;
set_param(model,'SimulationMode','normal');

% Set up Simulation Data Inspector for interactive viewing and comparison of
% simulation results
Simulink.sdi.view;
Simulink.sdi.clear;

% Run the simulation
simout_normal_run1 = sim(model, 'ReturnWorkspaceOutputs', 'on');

% Capture the results
Simulink.sdi.createRun('Run 1 (normal mode)', 'namevalue',...
                       {'simout_normal_run1'}, {simout_normal_run1});

Run a Second Simulation in Normal Mode

For the first simulation, the report showed that the achieved coverage was less than 100%. Enter the following commands to run a second simulation with different input signals that will increase the level of coverage to achieve 100% MC/DC coverage. Note that the model coverage report is configured to show cumulative coverage across both simulation runs.

counter_mode.signals.values = counter_mode_values_run2;
count_enable.signals.values = count_enable_values_run2;
set_param(model,'SimulationMode','normal');

simout_normal_run2 = sim(model, 'ReturnWorkspaceOutputs', 'on');

Simulink.sdi.createRun('Run 2 (normal mode)', 'namevalue',...
                       {'simout_normal_run2'}, {simout_normal_run2});

Configure the Model to Measure Code Coverage

Before running a SIL simulation, run the following commands to check whether a code coverage tool is available and configure the model to collect code coverage metrics.

% Check for available code coverage tools:
covToolPath = '';
ldraPath = coder.coverage.LDRA.getPath;
bullseyePath = coder.coverage.BullseyeCoverage.getPath;

% Configure the model to collect coverage metrics if the coverage tool is
% available
coverageSettings = get_param(model,'CodeCoverageSettings');
coverageSettings.TopModelCoverage='on';
if ~isempty(ldraPath)
    coverageSettings.CoverageTool='LDRA Testbed';
elseif ~isempty(bullseyePath)
    coverageSettings.CoverageTool='BullseyeCoverage';
else
    coverageSettings.CoverageTool='None';
end
set_param(model,'CodeCoverageSettings',coverageSettings);
set_param(model,'CodeExecutionProfiling','on');

Run a Simulation in SIL Mode

Coverage metrics for the normal mode simulations do not use generated code. With SIL simulations, you can use the same input stimulus signals on the generated code and measure code coverage instead of model coverage.

Enter the following commands to repeat the first two simulations in SIL mode. When both simulations are complete, click the link in the Command Window to open the code coverage report and view the cumulative code coverage results. The link is available only if you have a code coverage tool installed.

Follow the hyperlinks in the code coverage report to navigate back to the corresponding location in the block diagram. Then, by using the coverage display window you can directly open the corresponding section of the model coverage report.

counter_mode.signals.values = counter_mode_values_run1;
count_enable.signals.values = count_enable_values_run1;
set_param(model,'SimulationMode','software-in-the-loop');

simout_sil_run1 = sim(model, 'ReturnWorkspaceOutputs', 'on');

Simulink.sdi.createRun('Run 1 (SIL mode)', 'namevalue',...
                       {'simout_sil_run1'}, {simout_sil_run1});

% Run the second simulation in SIL mode
counter_mode.signals.values = counter_mode_values_run2;
count_enable.signals.values = count_enable_values_run2;
set_param(model,'SimulationMode','software-in-the-loop');

simout_sil_run2 = sim(model, 'ReturnWorkspaceOutputs', 'on');

Simulink.sdi.createRun('Run 2 (SIL mode)', 'namevalue',...
                       {'simout_sil_run2'}, {simout_sil_run2});
### Starting build procedure for model: rtwdemo_sil_topmodel
### Successful completion of build procedure for model: rtwdemo_sil_topmodel
### Preparing to start SIL simulation ...
Building with 'gcc'.
MEX completed successfully.
### Updating code generation report with SIL files ...
### Starting SIL simulation for component: rtwdemo_sil_topmodel
### Stopping SIL simulation for component: rtwdemo_sil_topmodel
### Starting build procedure for model: rtwdemo_sil_topmodel
### Generated code for 'rtwdemo_sil_topmodel' is up to date because no structural, parameter or code replacement library changes were found.
### Successful completion of build procedure for model: rtwdemo_sil_topmodel
### Preparing to start SIL simulation ...
### Updating code generation report with SIL files ...
### Starting SIL simulation for component: rtwdemo_sil_topmodel
### Stopping SIL simulation for component: rtwdemo_sil_topmodel

Simulation Data Inspector

The Simulation Data Inspector has been automatically opened to allow interactive viewing and analysis of the results. Use the "Compare Runs" tab to confirm that the SIL and normal mode logged signals are identical for both runs. This illustrated by the following screen shot.

Code Execution Profiling

You can check the execution time for each time step of the most recent SIL (or PIL) simulation.

% The name of the execution profile variable is specified under Configuration
% Parameters > Code Generation > Verification in the "Code
% profiling" section.
executionProfile = simout_sil_run2.get('executionProfile') %#ok<NOPTS>
 
Code execution profiling data for rtwdemo_sil_topmodel. To open a report,
enter the command <a href="matlab: report(executionProfile)">report(executionProfile)</a>.
 

Further Information

In this example, you have collected model coverage during a normal mode simulation and code coverage during a SIL simulation. You have navigated between the code coverage and model coverage reports and cross-checked the metrics from both reports. You can learn more about this and other topics from the following links: