You are on page 1of 6

MATLAB Digest

Best Practices for a MATLAB to C Workflow


Using Real-Time Workshop
By Houman Zarrinkoub and Grant Martin

Embedded software developers have long relied on MATLAB® for algorithm


Products Used
design and prototyping and on C code for implementation on embedded
■ MATLAB®
processors and DSPs. As a high-level language, MATLAB facilitates design
• Fixed-Point Toolbox™
exploration. In contrast, programming in C is well suited to optimizing DSPs
• Real-Time Workshop™
for performance, memory, and processing power. The challenge is to transi-
• Signal Processing Toolbox™
tion a design from the flexible development environment of MATLAB to the
constrained programming style of C. The solution is automatic translation of
MATLAB to embeddable C.

Manually translating MATLAB to C Challenges of Translating MATLAB is polymorphic. Functions


involves incorporating into the code MATLAB Concept Code into in MATLAB can process different types of
low-level details such as data-type as- Implementation Code input parameters and can apply a different
signments, memory allocations, and op- MATLAB has several advantages for de- algorithm to each type of parameter. For
timizations for computational load and sign exploration, such as polymorphism, example, the abs function computes the
memory. A great deal of effort is required matrix-based functions, and an interactive absolute value of real numbers and norm
to ensure that the MATLAB code and the programming environment. During trans- of complex numbers and can process sca-
C code remain equivalent. lation of an algorithm from MATLAB to C, lars, vectors, or matrices.
When your MATLAB algorithm uses the however, software designers face some im-
Embedded MATLAB™ language subset, the portant constraints. For example:
translation to C becomes unambiguous, en- MATLAB is a dynamically typed and C
abling you to focus on refining your design is a statically typed language. When writ-
rather than producing and verifying hand- ing a MATLAB program, you do not need
written C code. to define data types and sizes for your vari-
ables. While this flexibility makes it easy to
This article outlines the challenges in-
develop algorithms as proofs of concept,
volved in the manual translation from This kind of flexibility is not supported in
when it comes time for translation to C, the
MATLAB to C, demonstrates how to use C, which assigns a single algorithm to each
programmer must assign appropriate data
the Embedded MATLAB subset for auto- parameter type. To translate a polymorphic
types and sizes to all variables.
matic translation, and provides best prac- MATLAB function to C, the programmer
tices for coding your MATLAB algorithm must maintain separate function prototype
to improve the generated C code. for each possible parameter signature.

1 MATLAB Digest www.mathworks.com


MATLAB is based on compact matrix each column vector of cb. To visualize the identifies and reports on these unsupport-
notation. Most MATLAB expressions con- computed distances between any pair of ed lines of code.
taining vectors and matrices are compact, points, we call the plot_distances func- While it makes sense to use visualiza-
single-line expressions similar to the cor- tion inside the loop. We use the %#eml tion functions to debug and verify the
responding mathematical formula. The directive to turn on the MATLAB M-Lint algorithm, when we implement the al-
equivalent C code requires iterators, such as code analyzer and check the funtion code gorithm as C code, we must separate the
for loops, to express the matrix operations for errors and recommend corrections. offline analysis portions of the design
as a sequence of scalar computations. Figure 2 shows how the plot_distances from the online portions involved in em-
function helps us visualize the process of bedded C code generation. In our exam-
computing all distances in a 2D space and
Automating the MATLAB to C ple, we can make the algorithm compliant
Workflow finding the minimum value. with the Embedded MATLAB subset sim-
Automatic MATLAB to C conversion with ply by identifying and commenting out
Real-Time Workshop® addresses many of the plot_ distances function.
the challenges outlined in the previous sec-
Now we use the emlc command in
tion. For example, consider an algorithm
Real-Time Workshop to generate C code
depicted in the function euclidean.m .
for the Embedded MATLAB compliant
This algorithm minimizes the Euclidean
function euclidean.m .
distance between a column vector x and a
collection of column vectors contained in Typical syntax for translation is
To generate C code from this algorithm,
the matrix cb. The function has two output we must use only operators and functions >> emlc -eg {x,cb} –report euclidean.m
variables: y, the vector in cb with the mini- that are part of the Embedded MATLAB The example option (following the –eg
mum distance to x, and dist, the value of subset. Visualization functions, such as delimiter) sets the data types and dimen-
the minimum distance (Figure 1). plot, line, and grid, are not supported by sions of function variables by specifying
In the body of the Euclidean func- the Embedded MATLAB subset. When an example at the function interface. The
tion, we use the MATLAB function norm you open the euclidian.m function in the –report option opens the Embedded
to compute the distance between x and MATLAB editor, the M-Lint code analyzer MATLAB compilation report with

Figure 1. Source code for the euclidean.m function. Figure 2. Visualizing the computation of Euclidean distances by
the plot_distances function.

2 MATLAB Digest www.mathworks.com


Figure 3. C code generated automatically from the euclidean.m function displayed inside the Embedded MATLAB compilation report.

hyperlinks to C source files and header files many difficulties encountered in manual Accommodating Changes in Variable
generated from the MATLAB function. The MATLAB to C conversion are eliminated Dimensions
generated C code is created in a file named through automatic translation. In the MATLAB language, all data can vary
euclidean.c (Figure 3). in size. Embedded MATLAB supports vari-
Design Patterns for a MATLAB able-sized arrays and matrices with known
By using the example option, we declare to C Workflow upper bounds. This means you can accom-
the data type, size, and complexity of the In an embedded system, the size and data modate the use of variable-sized data for
variables x and cb in the function interface, type of each variable must be set before embedded implementations by using buffers
enabling the Embedded MATLAB engine implementation. In addition, if the per- of a constant maximum size and by address-
to assign data type and sizes automatically formance requirements are not met, the ing subportions of the constant-size buffers.
to all the local variable in the generated C algorithm’s memory and computational Within your Embedded MATLAB func-
program. The generated C code correctly footprint must be optimized. The following tions you can define variable-size inputs,
maps to zero-based indexing for access- sections examine design patterns that use outputs, and local variables, with known
ing array elements, and the vector opera- supported Embedded MATLAB features to upper bounds. For inputs and outputs,
tions are automatically mapped to scalar ensure that the generated C code adheres to you must specify the upper bounds explic-
computations with for loops. As a result, these requirements. itly at the function interface. For local data,

3 MATLAB Digest www.mathworks.com


Embedded MATLAB uses in-depth analy-
sis to calculate the upper bounds at compile
time. However, when the analysis fails to
detect an accurate upper bound, you must
specify them explicitly for local variables.
We update the euclidean.m function
to accommodate changes in dimensions
over which we compute the distances.
We want to compute only the distance
between first N elements of a given vec-
tor x with the first N elements of every
column vector contained in the matrix
cb. The resulting function, euclidean _
varsize.m , will have a third input argu-
ment, N (Figure 4).

The compilation of this function will


result in errors because we have not yet
specified an upper bound for the value of Figure 4. Input argument for euclidean _ varsize.m
N. As a result, the local variable 1:N will
have no specified upper bound. To impose
the upper bound we can constrain the value
of the parameter N in the first line of the
function by using the assert function
with relational operators (Figure 5).

The function varsize _ example.m shows


another common pattern, one where an
array such as Y is first initialized and then
grows in size based on a condition related to
the value of an input or local variable:

The compilation of this function will


again result in errors since we have not
specified an upper bound for the variable
Figure 5. Using the assert function with relational operators.
Y. To accommodate this type of size change
for the local variable Y, we can specify the
upper bound using the eml.varsize func-
tion for all instances of that local variable.
In this example we constrain a maximum

4 MATLAB Digest www.mathworks.com


dimension of 1-by-8 for the variable Y. In
the upper branch of the if statement, the
variable Y has a dimension of 1-by-6 and
in the lower branch, a dimension of 1-by-7.
The resulting function will be

Optimizing for Memory or


Computational Complexity
Another common refinement is to opti-
mize the generated C code for memory
and complexity. In our euclidean.m al- Figure 6. Optimized euclidean.m function.
gorithm, to compute the distance between
two points, norm takes the square root of
the squared values of each element of a giv-
en vector. Because computing the square
root is computationally expensive, we can
update our function by computing only
the sum of the squared elements, without
any loss in the intended behavior. The re-
sulting function, which has a much lower
computational load, uses the sum function Figure 7. Initializing the variable Y using the eml.nullcopy function.
supported by the Embedded MATLAB
language subset (Figure 6).

It may be desirable to reduce memo- tion. You can use Fixed-Point Toolbox™ to
Using Fixed-Point and Native Integer
ry footprint of the generated C code. In Data Types create fixed-point variables and perform
some cases, the initialization of new vari- By default, MATLAB uses 64-bit double- fixed-point computations. Since the
ables in your Embedded MATLAB func- precision numerical representation for Embedded MATLAB language subset sup-
tion may produce redundant copies in the variables created in the workspace. As con- ports the fixed-point data object (fi), by
generated C code. Although Embedded venient as this choice is for design explora- using Real-Time Workshop you can gener-
MATLAB technology eliminates many tion, it is not memory-efficient for real- ate pure integer C code from your Embed-
copies automatically, you can eliminate time processing of many common signals, ded MATLAB code. This usually involves
data copies that are not automatically such as image or audio signals represented modifying your original MATLAB func-
handled by declaring uninitialized vari- natively with word lengths of 8 or 16 bits. tion to declare variables based on integer
ables using the eml.nullcopy function. In To handle these types of signals and to or fixed-point representations.
Figure 7, the variable Y is initialized with implement your MATLAB algorithm on Our euclidean _ optimized.m func-
such a construction. target processors with limited word tion can process integer data types or fixed-
lengths, you must convert the design to a point data types as its input variables. To
fixed-point or integer-based representa- generate C code we only need to compile the
same function with integer or fixed-point

5 MATLAB Digest www.mathworks.com


Resources
visit
www.mathworks.com

Technical Support
www.mathworks.com/support

Online User Community


www.mathworks.com/matlabcentral

Demos
www.mathworks.com/demos

Training Services
www.mathworks.com/training

Third-Party Products
and Services
www.mathworks.com/connections

Worldwide CONTACTS
www.mathworks.com/contact

Figure 8. C code for euclidean _ optimized.m compiled with integer input variables. Computa- e-mail
tions are purely integer-based. info@mathworks.com

variables in the example option of the emlc data and fixed-point numerical represen-
command. The command syntax for input tations, are automatically translated to C © 2009 The MathWorks, Inc. MATLAB and Simulink
are registered trademarks of The MathWorks, Inc. See
variables of 16-bit signed integer type, for code, enabling you to focus on improving www.mathworks.com/trademarks for a list of additional
trademarks. Other product or brand names may be trade-
example, will be your design rather than maintaining mul- marks or registered trademarks of their respective holders.

>> emlc -eg {int16(x),int16(cb)} –re- tiple copies of the source code written in
port euclidean _ optimized.m different languages. ■
91768v00 10/09
The resulting generated C code contains
only integer C data types, and can be
readily compiled into fixed-point processors
(Figure 8). For More Information

A Common Language and ■C


 onvert MATLAB Code to Embedded C
Development Environment Using Embedded MATLAB
Automatic translation of MATLAB to C www.mathworks.com/embeddedc

with the Embedded MATLAB subset elimi- ■ F rom MATLAB to Embedded C.


DSP Design Line
nates the need to produce, maintain, and
www.dspdesignline.com/
verify hand-written C code. Design itera- howto/207800773
tions become easier, as you stay within the
MATLAB environment and take advantage
of its interactive debugging and visualiza-
tion capabilities. Many desirable features of
MATLAB programs, such as matrix-based
operations, polymorphism, variable-size

6 MATLAB Digest www.mathworks.com