Interactively Trace Between MATLAB Code and Generated C/C++ Code - MATLAB & Simulink (original) (raw)

This example shows how to trace between MATLAB® source code and the generated C/C++ code. Tracing between source code and generated code helps you to:

If you have Embedded Coder® and enable production of a code generation report with traceability, you can view MATLAB source code and generated C/C++ code next to each other. As you move your pointer over code, you can follow highlighted traces to the corresponding generated code or source MATLAB code.

Create the MATLAB Source Code

To illustrate interactive traceability, this example produces a report for generation of a C static library for a MATLAB function lpsolve that solves the linear program:

lpsolve

%Attempts to solve the linear program: % % maximize y = cx % subject to: Ax <= b, % where x >= 0 and b >= 0 % % using the dictionary form of the simplex algorithm. % % c must be a double, real row vector. % b must be a double, real column vector. % A must be a double, real, non-empty matrix with % size(A) = [length(b),length(c)]. % % Compare to % x = linprog(-c(:),A,b,[],[],zeros(length(c),1)) % y = c*x %
% Copyright 2011-2018 The MathWorks, Inc.

function [x,y] = lpsolve(c,A,b) %#codegen narginchk(3,3); m = int32(size(A,1)); n = int32(size(A,2)); if ~validInputs(c,A,b) % Something is wrong with the inputs. Return NaNs. x = nan(n,1); y = nan; return end cn = c; nIdx = 1:n; % indices of non-basic variables bIdx = n + (1:m); % indices of basic variables % Perform iterations. j = findPivotColumn(cn,nIdx); unbounded = false; while j > 0 && ~unbounded [i,r] = findPivotRow(j,A,b); if i == 0 || isinf(r) unbounded = true; else b(i) = r; % Take account of the variables entering and leaving the basis. entering = nIdx(j); leaving = bIdx(i); bIdx(i) = entering; nIdx(j) = leaving; [cn,A,b] = pivot(cn,A,b,i,j); j = findPivotColumn(cn,nIdx); end end % Construct the solution. if unbounded x = nan(n,1); y = inf; else x = zeros(n,1); y = 0; for k = 1:m j = bIdx(k); if j <= n x(j) = b(k); y = y + c(j)*x(j); end end end

%-------------------------------------------------------------------------------

function p = validInputs(c,A,b) coder.inline('never'); % All inputs must be double. p = isa(c,'double') && isa(A,'double') && isa(b,'double'); % All inputs must be real. p = p && isreal(c) && isreal(A) && isreal(b); % A must be a non-empty matrix. p = p && ismatrix(A) && ~isempty(A); % c must be a row-vector with length = size(A,2). p = p && isrow(c) && size(c,2) == size(A,2); % b must be a column-vector with length = size(A,1). p = p && iscolumn(b) && size(b,1) == size(A,1); % The elements of b must be non-negative. p = p && all(b(:) >= 0);

%-------------------------------------------------------------------------------

function [c,A,b] = pivot(c,A,b,i,j) % Pivot on element i,j. coder.inline('never'); m = int32(size(A,1)); aij = A(i,j); A(i,j) = 1; A(i,:) = A(i,:)/aij; for k = 1:m if k ~= i akj = A(k,j); A(k,j) = 0; A(k,:) = A(k,:) - akjA(i,:); b(k) = b(k) - akjb(i); end end cj = c(j); c(j) = 0; c = c - cj*A(i,:);

%-------------------------------------------------------------------------------

function j = findPivotColumn(c,idx) % Find a suitable variable to enter the basis using the smallest % subscript rule to prevent cycling. coder.inline('never'); j = int32(0); nc = int32(numel(c)); lastidx = int32(0); for k = 1:nc if c(k) > 0 && (lastidx < 1 || idx(k) < lastidx) j = k; lastidx = idx(k); end end

%-------------------------------------------------------------------------------

function [i,r] = findPivotRow(j,A,b) % Find the pivot row in column j of A and also return r = b(i)/A(i,j). coder.inline('never'); r = inf; i = int32(0); nb = int32(numel(b)); for k = 1:nb if A(k,j) > 0 rtmp = b(k)/A(k,j); if rtmp < r r = rtmp; i = k; end end end

%-------------------------------------------------------------------------------

The example also uses a test function lpsolve_test that callslpsolve with representative input values.

lpsolve_test

% Test function for lpsolve % % Copyright 2011-2018 The MathWorks, Inc.

function lpsolve_test() c = [2 3 1 1]; A = [2 3 1 -1;1 0 2 1;0 2 1 1]; b = [27;9;18]; [x,y] = lpsolve(c,A,b); x % display x y % display y

In a writable folder, create the files lpsolve.m andlpsolve_test.m by copying the code from the expanders in this section.

Prepare for Code Generation

Before you generate C/C++ code, it is a best practice to screen your MATLAB code for code generation readiness.

coder.screener('lpsolve')

The code generation readiness report indicates that lpsolve is suitable for code generation.

It is also a best practice to check for run-time issues by generating and testing a MEX function.

c = [2 3 1 1]; A = [2 3 1 -1;1 0 2 1;0 2 1 1]; b = [27;9;18]; codegen lpsolve -args {c A b} -test lpsolve_test

Running test file: 'lpsolve_test' with MEX function 'lpsolve_mex'.

x =

 5
 7
 0
 4

y =

35

codegen successfully generates and runs the MEX function.

Produce a Code Generation Report with Traceability

To generate a report that has interactive traceability:

cfg = coder.config('lib', 'ecoder', true); codegen -config cfg lpsolve -args {c A b} -report

Access Trace Mode in the Report

To open the code generation report, click View report.

In the code pane, you see lpsolve.m.

To enable tracing, on the Report tab, click Trace Code.

You see the MATLAB source code and the generated C code next to each other.

Trace Code

You can trace from the MATLAB code to the C code or from the C code to the MATLAB code. Traceable code is marked with blue on the side that you are tracing from and with orange on the side that you are tracing to. As you move your pointer over traceable code, the code is highlighted in purple and you see the traces to the corresponding code on the other side. When you select highlighted code by clicking it, the code becomes yellow and you can see the traces even when you move your pointer away from the selection. The code remains selected until you press Esc or select different code. To change the side that you are tracing from, select code on the other side.

Explore tracing in the example report.

  1. In the MATLAB code, point to the while-loop that starts at line 38 and scroll down until the entire while-loop is in view.

    You see this symbol that tells you that the highlighted MATLAB code has one trace that is not in view.

    You see the corresponding C code in a separate window in the C code pane.
  2. In the C code pane, scroll down until you see the C code that corresponds to the while loop.
  3. In the MATLAB code, move your pointer over different syntax elements in thewhile loop. Highlight variables, expressions, and code blocks.
    When you move your pointer over expressions that are part of larger expressions, different shades of purple help you to find the relevant expression in the corresponding C code. For example, at line 43, pause overi.
  4. In the MATLAB code, move your pointer back to thewhile-loop that starts at line 38. When the entire loop is highlighted in purple, select it by clicking. When you move your pointer outside of the trace, the yellow highlighting identifies the selected trace.

    To clear the selection, press Esc or select different code.

View Multiple Traces

When code traces to more than one place in the corresponding source or generated code:

In the report for lpsolve, view multiple traces.

  1. Pause over line 36.
    At the top of the code pane, you see that line 36 has two traces.
  2. Select line 36.
    At the top of the code pane, you see the location of the first trace.
  3. To list all traces, click the arrow to the right of the traces.

View Traces to Different Files

In the code generation report for lpsolve, all traces from the MATLAB code go to one C file lpsolve.c. If MATLAB code traces to multiple C files, above the C code, you see a symbol such as that provides the number of additional files in which you can find a trace. If you click the symbol, you can select the file that you want to see. If you select the MATLAB code, then you can select the trace that you want to see.

Likewise, above the MATLAB source code, a symbol such as indicates that the highlighted C code traces to multiple MATLAB files.

Switch the Locations of the Source and Generated Code

  1. To view lpsolve.c on the left side of the code pane, in the list of generated files, click lpsolve.c.
  2. To view the MATLAB code on the left side of the code pane, click a MATLAB function, for example, lpsolve.

When you are not in trace mode:

When you are in trace mode, to enable MATLAB code tooltips and C code links, hold down Ctrl. MATLAB code tooltips are available only for a selected MATLAB function.

In the report for lpsolve, view type information for a variable.

  1. In the MATLAB Source pane, selectpivot.
  2. In the code pane, hold down Ctrl and pause over the input argument i.

Note

On a Macintosh platform, use the Command key instead ofCtrl.

Disable Traceability

To produce a code generation report that does not include traceability:

See Also

coder.EmbeddedCodeConfig