Embedded Matlab
Embedded Matlab
www.mathworks.com Web
comp.soft-sys.matlab Newsgroup
www.mathworks.com/contact_TS.html Technical Support
508-647-7000 (Phone)
508-647-7001 (Fax)
Trademarks
MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See
www.mathworks.com/trademarks for a list of additional trademarks. Other product or brand
names may be trademarks or registered trademarks of their respective holders.
Patents
The MathWorks products are protected by one or more U.S. patents. Please see
www.mathworks.com/patents for more information.
Revision History
October 2008 Online only New for Release 2008b
March 2009 Online only Revised for Release 2009a
September 2009 Online only Revised for Release 2009b
Contents
iii
Files for This Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7
About the Tutorial Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7
Location of Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-8
Names and Descriptions of Files . . . . . . . . . . . . . . . . . . . . . 2-8
iv Contents
Next Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-11
Best Practices Used in This Section . . . . . . . . . . . . . . . . . . . 4-12
Generating C Code
5
Generating C Code Using emlc . . . . . . . . . . . . . . . . . . . . . . 5-2
Prerequisites for Generating C Code . . . . . . . . . . . . . . . . . . 5-2
Contents of the Example Build Script . . . . . . . . . . . . . . . . . 5-2
Using the Example Build Script . . . . . . . . . . . . . . . . . . . . . . 5-3
Comparing the Generated C Code to Original M-Code . . . . 5-6
Next Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-8
Best Practices Used in This Section . . . . . . . . . . . . . . . . . . . 5-8
v
How to Generate C Code for Your Modified M-Code . . . . . . 6-15
How to Test Your MEX Function . . . . . . . . . . . . . . . . . . . . . 6-15
Next Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-15
vi Contents
-o Specify Output File Name . . . . . . . . . . . . . . . . . . . . . . . . 8-2
-report Generate Compilation Report . . . . . . . . . . . . . . . . . 8-3
Index
vii
viii Contents
1
Introduction to the
Embedded MATLAB Subset
1-2
When to Use the Embedded MATLAB™ Subset
For the function, command, or block that applies, see “Which Embedded
MATLAB Feature to Use” on page 1-4.
1-3
1 Introduction to the Embedded MATLAB™ Subset
1-4
Which Embedded MATLAB™ Feature to Use
1-5
1 Introduction to the Embedded MATLAB™ Subset
To... Use...
Deploy an application that uses “MATLAB Compiler™”
handle graphics
Use Java™ “MATLAB® Builder JA”
Use toolbox functions that the Toolbox functions that you rewrite
Embedded MATLAB subset does for embedded applications
not support
Deploy M-based GUI applications “MATLAB Compiler™”
on a supported MATLAB host
Deploy web-based or Windows® “MATLAB® Builder NE”
applications
Interface C code with MATLAB MATLAB mex function
1-6
Benefits of Using the Embedded MATLAB™ Subset
1-7
1 Introduction to the Embedded MATLAB™ Subset
Tutorial Prerequisites
In this section...
“What You Need to Know” on page 1-8
“Required Products” on page 1-8
Required Products
To complete this tutorial, you must install the following products:
• MATLAB
• Simulink
• Fixed-Point Toolbox (required when using fixed-point capabilities)
• Real-Time Workshop
• C compiler (a default C compiler is supplied with MATLAB)
1-8
Tutorial Prerequisites
1-9
1 Introduction to the Embedded MATLAB™ Subset
1-10
2
Generating C Code
from MATLAB Code for
Embedded Applications
To get you started quickly, this tutorial guides you through hands-on exercises
for each task in the flow chart. When you get to task 4, you might need to
iterate between generating C code and elaborating your Embedded MATLAB
compliant code. Elaboration is the process of refining the design of your
M-code as you work toward producing the most efficient, embeddable C code.
To view the complete list of the best practices recommended in this tutorial,
see Chapter 8, “Best Practices for Working with the Embedded MATLAB
Subset”.
2-2
Design Considerations for Code Generation
• Data types
C uses static typing. Therefore, you must declare the data type of all
variables at compile time.
• Array sizing
The Embedded MATLAB subset supports variable-size arrays and matrices
with known upper bounds. With this feature, you can define inputs,
outputs, and local variables in Embedded MATLAB functions to represent
data that varies in size at runtime.
For more information, see “Generating Code for Variable-Size Data” in the
Embedded MATLAB™ User’s Guide.
Note The LMS filter example in this tutorial uses static array sizing.
• Memory use
Because dynamic memory allocation is not suitable for mission or
safety-critical applications, the Embedded MATLAB subset supports only
static memory allocation in the generated code.
• Speed
Because embedded applications need to run in real time, the code must be
fast enough to meet the required clock rate.
• Memory
Embedded processors have a limited amount of available memory. As a
result, data storage must be minimized, and the code must be as compact
as possible.
To learn how to apply these design considerations, you work with “Example:
The LMS Filter” on page 2-4.
2-3
2 Generating C Code from MATLAB® Code for Embedded Applications
Description
A least mean squares (LMS) filter is an adaptive filter that adjusts its transfer
function according to an optimizing algorithm. You provide the filter with
an example of the desired output together with the input signal. The filter
then calculates the filter weights, or coefficients, that produce the least mean
squares of the error between the output signal and the desired signal.
The example for this tutorial uses a LMS filter to remove the noise in a music
recording. This example uses two inputs. The first input is the distorted
signal: the music recording plus noise. The second input is the noise. The
filter works to eliminate the difference between these two signals and outputs
the difference, which, in this case, is the clean music recording. When you
start the simulation, you hear both noise and the music. Over time, the
adaptive filter filters out the noise so you hear only the music.
Algorithm
This tutorial uses the least mean squares (LMS) algorithm to remove noise
from an input signal. The LMS algorithm computes the filtered output, filter
error, and filter weights given the distorted and desired signals.
The LMS algorithm at the start of the tutorial uses a batch process to filter
the audio input. This algorithm is suitable for MATLAB, where you are likely
to load in the entire signal and process it all at once. However, a batch process
is not suitable for processing a signal in real time. As you work through the
tutorial, you refine the design of the filter to convert the algorithm from
batch-based to stream-based processing.
2-4
Example: The LMS Filter
Note The LMS filter example in this tutorial uses static array sizing. The
Embedded MATLAB subset supports variable-size arrays and matrices with
known upper bounds. With this feature, you can define inputs, outputs,
and local variables in Embedded MATLAB functions to represent data that
varies in size at runtime. For more information, see “Generating Code for
Variable-Size Data” in the Embedded MATLAB™ User’s Guide.
for n = 1:N
signal_out(n) = weights' * distorted(n:n+L-1);
err(n) = desired(n) - signal_out(n) ;
weights = weights + mu*err(n)*distorted(n:n+L-1);
end
where N is the length of the input signal, L is the filter length, and mu is the
adaptation step size.
LMS algorithms have a step size that determines the amount of correction
to apply as the filter adapts from one iteration to the next. Choosing the
appropriate step size requires experience in adaptive filter design. A step
size that is too small increases the time for the filter to converge. Filter
convergence is the process where the error signal (the difference between the
output signal and the desired signal) approaches an equilibrium state over
time. A step size that is too large might cause the adapting filter to overshoot
the equilibrium and become unstable, which is undesirable. Generally,
smaller step sizes improve the stability of the filter at the expense of the
time it takes to adapt.
2-5
2 Generating C Code from MATLAB® Code for Embedded Applications
• Convolution
The convolution for the filter is performed in:
What is convolution?
• Adaptation
The new value of the filter weights is the old value of the filter weights plus
a correction factor that is based on the error signal, the distorted signal,
and the adaptation step size:
Reference
Haykin, Simon, Adaptive Filter Theory, Prentice-Hall, Inc., 1996
2-6
Files for This Tutorial
2-7
2 Generating C Code from MATLAB® Code for Embedded Applications
Location of Files
The tutorial files are located in the folder
matlabroot/toolbox/eml/tutorial.
You will need to copy these files to a local folder. Instructions on how to copy
the files are provided in “Copying Files Locally” on page 3-4.
2-8
Files for This Tutorial
2-9
2 Generating C Code from MATLAB® Code for Embedded Applications
2-10
3
In this part of the tutorial, you examine the LMS Filter example M-code and
make it compliant with the Embedded MATLAB subset.
3-2
Considerations for Making Your Code Compliant
After successful compilation, emlmex generates a MEX function that you can
use to test your implementation in MATLAB.
Where to Go Next
The next section of the tutorial, “Making the LMS Filter Code Embedded
MATLAB Compliant” on page 3-4, shows you how to use M-Lint and emlmex
to make the LMS Filter code compliant with the Embedded MATLAB subset.
3-3
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
cd([matlabroot '/toolbox/eml'])
3 Copy the tutorial subfolder and its contents to your local folder by typing:
copyfile('tutorial', 'destination')
mex -setup
3-4
Making the LMS Filter Code Embedded MATLAB™ Compliant
Select a compiler:
[1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2008b\sys\lcc
[0] None
Compiler:
MATLAB outputs:
Done . . .
3-5
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
To begin the process of making your M-code compliant with the Embedded
MATLAB subset, you work with the file emldemo_lms_01.m.
1 Set your MATLAB current folder to the folder that contains your files for
this tutorial. At the MATLAB command line, enter:
cd folder
where folder is the full path name of the folder containing your files. See
“Viewing and Changing the Current Folder Using the Current Folder
Browser” in the MATLAB Desktop Tools and Development Environment
documentation for more information.
edit emldemo_lms_01.m
The M-Lint message indicator in the top right corner of the MATLAB
Editor is green, which indicates that M-Lint has not detected any errors,
warnings, or opportunities for improvement in the code.
M-Lint message
indicator
Green = no errors
3-6
Making the LMS Filter Code Embedded MATLAB™ Compliant
The M-Lint message indicator remains green indicating that M-Lint has
not detected any Embedded MATLAB related issues. For more information
on using M-Lint, see “Checking M-File Code for Problems Using the
M-Lint Code Analyzer” in the MATLAB Desktop Tools and Development
documentation.
a To match the function name to the file name, change the function name
to my_emldemo_lms_01.
Note If you do not match the filename to the function name, M-Lint
warns you that these names are not the same and highlights the function
name in orange to indicate that it can provide an automatic fix. For
more information, see “Making Changes Based on M-Lint Messages”
in the MATLAB documentation.
d Click Save.
Now you are ready to compile the LMS Filter example code using emlmex.
3-7
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
data = load('handel.mat')
data =
y: [73113x1 double]
Fs: 8192
N = length(data.y)
N = 73113
emlmex reports the following error, which includes a link to the offending
line of code and a link to an error report:
3-8
Making the LMS Filter Code Embedded MATLAB™ Compliant
You can also view errors by clicking the Open error report link. The
error report provides a complete list of all the errors and warnings
detected by emlmex. You must fix the first error in the list before
addressing subsequent errors and warnings because many of these may
be related to the first error. See “Working with Compilation Reports” in
the Embedded MATLAB User’s Guide for more information.
The my_emldemo_lms_01 file opens with the cursor at the offending line
of code;
emlmex detects that you are changing the size of the array variable
distorted after it has been defined. Because you have not specified that
distorted is a variable-size array, you cannot change its size at run time.
7 Add the suffix _pad to the variable distorted on the left-hand side of the
assignment statement to create a new variable distorted_pad, which
contains the padded signal. This line of code becomes:
The M-Lint message indicator turns orange to alert you that the file has
at least one warning. M-Lint underlines the offending code in orange and
places an orange marker to the right of it.
3-9
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
M-Lint warning
message indicator.
Click indicator to
go to first warning
%#eml compilation
directive
M-Lint warning
marker.
- Hover over marker
to see message
- Click marker to go
to offending code
9 To address this warning, change the filter update loop to use the new
variable distorted_pad instead of the original variable distorted. You
need to make this change in two places: once each in the first and third
lines inside the for-loop.
for n = 1:N
signal_out(n) = weights' * distorted_pad(n:n+L-1);
err(n) = desired(n) - signal_out(n);
weights = weights + mu*err(n)*distorted_pad(n:n+L-1);
end
3-10
Making the LMS Filter Code Embedded MATLAB™ Compliant
The M-Lint message indicator in the top right edge of the code turns green,
which indicates that you have fixed all the errors and warnings detected by
M-Lint.
10 Save the file and compile it again. At the MATLAB command line, enter:
emlmex reports the following error, which includes a link to the offending
line of code and a link to an error report:
The my_emldemo_lms_01 file opens with the cursor at the offending line
of code:
figure;
The Embedded MATLAB subset does not support the MATLAB function
figure. When you call an unsupported MATLAB function, you must
declare it to be extrinsic so MATLAB can execute it, but Embedded
MATLAB does not try to generate code for it.
3-11
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
Alternatively, you can call the figure function using feval, see “Calling
MATLAB Functions Using feval” in the Embedded MATLAB User’s Guide
for more information.
12 The functions stem , title, and num2str are also unsupported MATLAB
functions. Declare all four functions extrinsic by adding the following
declaration after the function signature:
% Version Number:
k = 1;
% Signal length:
N = length(distorted);
if length(desired) == N
% Filter coefficients:
weights = zeros(L,1);
3-12
Making the LMS Filter Code Embedded MATLAB™ Compliant
for n = 1:N
signal_out(n) = weights' * distorted_pad(n:n+L-1);
err(n) = desired(n) - signal_out(n) ;
weights = weights + mu*err(n)*distorted_pad(n:n+L-1);
end
else
end
end
13 Save the file and compile it again. At the MATLAB command line, enter:
emlmex reports the following error. Note that the line number in your error
report may not match the one shown here because you have modified the
code.
The my_emldemo_lms_01.m file opens with the cursor at the offending line
of code:
3-13
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
weights = zeros(L,1);
The issue: you are using the input parameter L to define the size of the
variable weights. Because you are using static array sizing, emlmex must
be able to determine the size of all array variables at code generation time.
Because the value of L is not known until run time, emlmex generates an
error.
Note The LMS filter example in this tutorial uses static array sizing.
However, the Embedded MATLAB subset supports variable-size arrays
and matrices with known upper bounds. With this feature, you can define
inputs, outputs, and local variables in Embedded MATLAB functions to
represent data that varies in size at runtime. For more information, see
“Generating Code for Variable-Size Data” in the Embedded MATLAB™
User’s Guide.
b Set the size of the filter length at the start of the function after the
function signature:
% Filter Length:
L = 32;
16 Save the file and compile my_emldemo_lms_01.m again, this time specifying
only two input parameters:
3-14
Making the LMS Filter Code Embedded MATLAB™ Compliant
emlmex reports the following error. Note that the line number in your error
report may not match the one shown here because you have modified the
code.
The my_emldemo_lms_01 file opens with the cursor at the offending line
of code:
3-15
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
The filter update loop code should now look like this:
a To match the function name to the file name, change the function name
to my_emldemo_lms_01_compliant.
b In the MATLAB Editor, select Save As from the File menu.
d Click Save.
e Close my_emldemo_lms_01_compliant.m.
Next Task
The LMS Filter example code is now Embedded MATLAB compliant. You are
ready to begin the next task in this tutorial, Chapter 4, “Testing Compliant
Code in MATLAB”.
See Also
• For a complete list of supported operators and programming statements,
see “Supported Operators” in the Embedded MATLAB User’s Guide.
• For a complete list of supported functions, see Embedded MATLAB
Reference.
3-16
Making the LMS Filter Code Embedded MATLAB™ Compliant
Note To see the complete list of best practices used in this tutorial, see
Chapter 8, “Best Practices for Working with the Embedded MATLAB Subset”.
Use the MATLAB Compare Against option to compare two M-files to examine
differences between files. See “Comparing Files” on page 8-9 for more
information.
Use the -eg option to specify the input properties by example. emlmex extracts
the data types and sizes of the variables listed in the cell array following
the -eg option. It is important to understand that it is not the values of the
variables that you are specifying with the -eg option, but the data types and
array dimensions of these parameters. The -eg option is easy to use, does not
alter your M-code, and is designed for prototyping a function that has a small
number of primary inputs. Alternatively, you can use the assert function to
3-17
3 Making Your M-Code Compliant with the Embedded MATLAB™ Subset
define properties of primary function inputs directly in your M-file. See “-eg
Specify Input Parameters by Example” on page 8-2 for more information.
Use the -o option to specify an output file name for the generated MEX
function that is different from the name of the original M-file so that you can
test the M-code and MEX function and compare the results. See “-o Specify
Output File Name” on page 8-2 for more information. If you do not specify
an output file name, emlmex gives the MEX file the same name as the M-file.
It assigns a new default platform-specific file extension to the MEX file, for
example, .mexw32 for 32-bit Windows. (See “Naming Conventions” in the
Embedded MATLAB User’s Guide for more information.) If you subsequently
refer to this file by its name only (without the extension), MATLAB selects
the MEX file in accordance with file precedence rules. See “File Precedence”
in MATLAB Programming Fundamentals.
3-18
4
In this part of the tutorial, you use a build script to generate a MEX function
for your Embedded MATLAB compliant code. You then test the MEX function
in MATLAB to verify that it is functionally equivalent to the original M-code.
close all;
clear all;
clc;
N = 73113;
where:
4-2
Generating MEX Functions Using Build Scripts
Note Remove the clear all command from the build scripts if you
want to preserve breakpoints for debugging.
- clc clears all input and output from the Command Window display,
giving you “clean screen”.
• N = 73113 sets the music sample size to the size of the handel.mat
audio sample. You need the audio sample length to specify the size of the
emldemo_lms_02 function input parameters. See “Compiling M-Code Using
emlmex” on page 3-6 for more information.
• emlmex is a command that:
- Compiles the file emldemo_lms_02.m, which contains the same code as
the file my_emldemo_lms_01_compliant.m that you saved at the end of
“Compiling M-Code Using emlmex” on page 3-6. You can verify that
these two files are the same by using the MATLAB Compare Against
option.
- Uses the -eg option to instruct emlmex to compile the file using the
sample input parameters { zeros(N,1) zeros(N,1) }. The -eg option
provides Embedded MATLAB with examples or prototypes of the input
variables, specifying their data types, array dimensions, and numeric
complexity but not their actual values. In this case, the prototypes are
N-by-1 vectors of all zeros represented as real-valued, double-precision
floating-point numbers.
- Uses the -report option to instruct emlmex to generate a compilation
report.
- Uses the -o option to instruct emlmex to generate the MEX function in a
file named emldemo_lms_02_mex.
See “Recommended Compilation Options for emlmex” on page 8-2 for more
information.
4-3
4 Testing Compliant Code in MATLAB®
1 Set your MATLAB current folder to the folder that contains your files for
this tutorial. At the MATLAB command line, enter:
cd folder
where folder is the full path name of the folder containing the files. See
“Viewing and Changing the Current Folder Using the Current Folder
Browser” in the MATLAB Desktop Tools and Development Environment
documentation for more information.
Note The file extension you see depends on the platform on which you
are running. MATLAB adds a platform-specific file extension to the MEX
output file. for example. For example, on 32-bit Windows platforms, the
output file is emldemo_lms_02_mex.mexw32. See “Naming Conventions” in
the Embedded MATLAB User’s Guide for more information.
4-4
Testing MEX Functions
Set Up
Clears your MATLAB workspace and sets the playaudio flag to true to play
the filtered audio signal at the end of the test script. If you do not want to
listen to the audio output, set the playaudio flag to false.
%% Setting up:
% Initialize:
close all;
clear all;
clc;
% Flag to play audio:
playaudio = true;
4-5
4 Testing Compliant Code in MATLAB®
% Filter length:
L = 32;
% samples
4-6
Testing MEX Functions
% Band-limited AWGN:
load emldemo_lms_filter.mat;
lambda = 1.0;
whiteNoise = lambda*randn(N,1);
noise = filter(b,1,whiteNoise);
% Distorted signal:
distorted = desired + noise;
%% Find differences:
diff.signal = test.signal - gold.signal;
diff.error = test.error - gold.error;
diff.impulse = test.impulse - gold.impulse;
4-7
4 Testing Compliant Code in MATLAB®
Output Results
Plots the differences between the output signals, error signals, and impulse
responses of the two filters and plays the filtered audio signal if playaudio is
enabled.
%% Plot differences:
figure;
subplot(3,1,1);
plot(diff.signal);
title({'Algorithm Under Test versus Golden Reference'
'Output Signal'});
subplot(3,1,2);
plot(diff.error);
title('Error Signal');
subplot(3,1,3);
stem(diff.impulse);
title('Impulse Response');
%% Play sound:
if playaudio
sound(test.error);
end
As MATLAB processes the test script, you see and hear outputs. Because
playaudio is enabled, the filtered music is played. Initially, you hear the
audio signal distorted by noise. Then, during the first few seconds, the filter
attenuates the noise gradually, until you hear only the music playing with
very little noise remaining.
4-8
Testing MEX Functions
4-9
4 Testing Compliant Code in MATLAB®
4-10
Testing MEX Functions
Embedded MATLAB code and the MATLAB code might not be identical,
so minor differences can occur due to rounding.
These plots show that the difference between the modified filter and the
golden reference is insignificant because:
- The difference between the filter output signals is of the order 1 x 10-15.
- The difference between the filter error signals is of the order 1 x 10-15.
- The difference between the filter impulse responses is of the order 1 x
10-16 or less.
This result indicates that your Embedded MATLAB compliant filter code is
functionally equivalent to the original M-code.
Next Task
You have generated a MEX function for your Embedded MATLAB compliant
M-code and verified that it is functionally equivalent to your original M-code.
4-11
4 Testing Compliant Code in MATLAB®
Now you are ready to begin the next task in this tutorial, Chapter 5,
“Generating C Code”.
Use a consistent file naming convention, for example, include build in your
file name to indicate that this is a build script. See “File Naming Conventions”
on page 8-15 for more details.
Use the MATLAB Compare Against option to compare two M-files to examine
differences between files. See “Comparing Files” on page 8-9 for more
information.
Use the -report option to generate an HTML report with links to your M-code
files and compile-time type information for the variables and expressions in
your M-code. This information simplifies finding sources of error messages
and aids understanding of type propagation rules. If this option is not
specified, emlmex generates a report only if there are compilation errors or
warnings. See “-report Generate Compilation Report” on page 8-3 for more
information.
Separate your core algorithm from your test bench. Create a separate test
script to do all the pre- and post-processing such as loading inputs, setting up
input values, calling the function under test, and outputting test results.
4-12
5
Generating C Code
In this part of the tutorial, you use Embedded MATLAB Coder (emlc) to
generate C code from your Embedded MATLAB compliant code.
5 Generating C Code
• MATLAB
• Simulink
• C compiler (a default compiler is supplied with MATLAB)
emldemo_lms_build_02_lib.m contains:
close all;
clear all;
clc;
N = 73113;
5-2
Generating C Code Using emlc
-report ...
-c ...
-T rtw:lib
where:
• clear all removes all variables, functions, and MEX-files from memory,
leaving the workspace empty. It also clears all breakpoints.
Note Remove the clear all command from the build scripts if you want
to preserve break points for debugging.
1 Set your MATLAB current folder to the folder that contains your files for
this tutorial.
3 To view the compilation report, click the Open compilation report. link.
5-3
5 Generating C Code
5-4
Generating C Code Using emlc
5-5
5 Generating C Code
5 To view the generated C code, click the link to the target source file, for
example, emldemo_lms_02.c.
5-6
Generating C Code Using emlc
You can easily compare the generated C code to your original M-code. In
the generated C code:
5-7
5 Generating C Code
Next Task
You have generated C code for your Embedded MATLAB compliant M-code.
You are ready to begin the next task in this tutorial, Chapter 6, “Elaborating
Your Algorithm for Embedded Implementation”.
During the development cycle, use the -c option for generating C code without
building an executable. This option enables you to iterate rapidly between
modifying M-code and generating C code. See “-c Generate Code Only” on
page 8-4 for more information.
5-8
6
Elaborating Your
Algorithm for Embedded
Implementation
In this part of the tutorial, you determine what changes you can make to your
M-code to produce more efficient, embeddable C code. This process of evolving
your M-code design is known as elaboration. It is common to iterate between
generating C code and elaborating your Embedded MATLAB compliant code
until you achieve optimal results.
Now you are ready to modify your design to make it more suitable for
embedded implementation.
Prerequisites
Open the file emldemo_lms_02.c which is in
folder\emcprj\rtwlib\emldemo_lms_02, where folder is the folder that
contains your tutorial files.
6-2
Modifying the Filter to Accept a Variable Length Signal
/* Function Definitions */
void emldemo_lms_02(const real_T eml_distorted[73113],
const real_T eml_desired[73113], real_T eml_signal_out[73113],
real_T eml_err[73113], real_T eml_weights[32])
% Version Number:
k = 3;
% Filter Length:
L = uint32(32);
% Adaptation step-size:
mu = 4/(32*1024);
% Maximum signal length:
MaxLength = length(distorted);
% Filter coefficients:
weights = zeros(L,1);
6-3
6 Elaborating Your Algorithm for Embedded Implementation
• The data type of the filter length L has changed from double to uint32.
You must declare L an integer because it is used in the matrix index
distorted_pad(n+(0:L-1)) where n is an integer. If L is not an integer,
a compilation error occurs.
• The new input parameter N, which contains the actual size of the audio
sample, controls the filter loop to ensure that the loop processes only valid
data:
for n = 1:N
signal_out(n) = weights' * distorted_pad(n+(0:L-1));
err(n) = desired(n) - signal_out(n) ;
weights = weights + mu*err(n)*distorted_pad(n+(0:L-1));
6-4
Modifying the Filter to Accept a Variable Length Signal
end
• MaxLength defines the maximum size of the input signal. Set MaxLength
to a value that is greater than the biggest signal size you are likely to
encounter. In this case, MaxLength is set to a value of 131072 (128*1024)
samples.
• X = zeros(MaxLength,1) preallocates a fixed-size array using MaxLength.
X defines the properties of the desired and distorted input parameters at
code generation time.
• the –T mex option instructs emlc to generate a MEX function. See
“Recommended Compilation Options for emlc” on page 8-4 for more
information.
6-5
6 Elaborating Your Algorithm for Embedded Implementation
• The script compares the first N elements of the output signal, which contain
the filtered audio sample, to the golden reference.
%% Find differences:
diff.signal = test.signal(1:N) - gold.signal;
diff.error = test.error(1:N) - gold.error;
diff.impulse = test.impulse - gold.impulse;
6-6
Modifying the Filter to Use Streaming
What Is Streaming?
A streaming filter is called repeatedly to process fixed-size chunks of input
data, or frames, until it has processed the entire input signal. The frame size
can be as small as a single sample, in which case the filter would be operating
in a sample-based mode, or up to a few thousand samples, for frame-based
processing.
6-7
6 Elaborating Your Algorithm for Embedded Implementation
persistent weights;
persistent fifo;
% Filter length:
L = uint32(32);
% Signal length:
N = length(distorted);
if length(desired) == N
if isempty(weights)
6-8
Modifying the Filter to Use Streaming
% Filter coefficients:
weights = zeros(L,1);
% FIFO Shift Register:
fifo = zeros(L,1);
end
persistent weights;
persistent fifo;
fifo = zeros(L,1);
6-9
6 Elaborating Your Algorithm for Embedded Implementation
weights_out = weights;
6-10
Modifying the Filter to Use Streaming
• You must now specify the frame size and calculate the number of frames
in your audio sample:
% Frame size:
FrameSize = 2048;
% Number of frames
NumFrames = ceil(N/FrameSize);
• For test purposes, you must zero pad the input signals so that the number
of samples is an integer multiple of the frame size.
% Zero-pad:
whiteNoise = [ whiteNoise ; zeros(FrameSize*NumFrames - N,1) ];
distorted = [ distorted ; zeros(FrameSize*NumFrames - N,1) ];
• When you test the modified algorithm, you call it repeatedly (using a for-
loop) until it has processed the entire input signal:
6-11
6 Elaborating Your Algorithm for Embedded Implementation
ls ([matlabroot '\toolbox\matlab\audiovideo\*.mat'])
6-12
Adding Adapt and Reset Controls
persistent weights;
persistent fifo;
% Filter length:
L = uint32(32);
% Adaptation step size:
mu = 4/(32*1024);
% Signal length:
N = length(distorted);
if length(desired) == N
if ( reset || isempty(weights) )
% Filter coefficients:
weights = zeros(L,1);
6-13
6 Elaborating Your Algorithm for Embedded Implementation
if ( reset || isempty(weights) )
% Filter coefficients:
weights = zeros(L,1);
% FIFO Shift Register:
fifo = zeros(L,1);
end
• The new parameter adapt is used to control whether the filter coefficients
are updated or not:
6-14
Adding Adapt and Reset Controls
if adapt
weights = weights + mu*err(n)*fifo;
end
• You must now set up the values of the Reset and Adapt controls before
using the filter. In this test, the controls are set so that the filter is
constantly adapting:
reset = false;
adapt = true;
• You pass in the values of Reset and Adapt when you call the filter:
[ yt et test.impulse ] = ...
emldemo_lms_05_mex(whiteNoise(indexRange), ...
distorted(indexRange), reset, adapt);
Next Task
If you want to integrate your M-code with Simulink, perform the second
procedure in this tutorial, Chapter 7, “Integrating Your Embedded MATLAB
Compliant Code with Simulink”.
6-15
6 Elaborating Your Algorithm for Embedded Implementation
Next Steps
To... See...
Learn more about using the Embedded Embedded MATLAB™ User’s Guide
MATLAB subset
Speed up fixed-point M-code “Working with Embedded MATLAB MEX” in
the Real-Time Workshop User’s Guide
Integrate custom C code into MATLAB and “Converting MATLAB Code to C Code” in the
generate embeddable code Embedded MATLAB User’s Guide
Integrate custom C code into an Embedded eml.ceval in the Embedded MATLAB
MATLAB function Reference
Generate HDL from M-code www.mathworks.com/products/slhdlcoder
Learn more about the best practices used in Chapter 8, “Best Practices for Working with
this tutorial the Embedded MATLAB Subset”
6-16
Where to Learn More
Product Help
The MathWorks technical documentation is available online from the Help
menu on the MATLAB desktop.
For... See...
Embedded MATLAB subset usage “Working with the Embedded
MATLAB Subset” in the Embedded
MATLAB User’s Guide
A list of Embedded MATLAB Embedded MATLAB Reference
functions
What’s new Embedded MATLAB™ Release Notes
6-17
6 Elaborating Your Algorithm for Embedded Implementation
6-18
7
The first part of this tutorial guided you through the tasks for generating C
code from your M-code. This part of the tutorial guides you through the steps
involved in integrating your M-code with Simulink. You may integrate your
M-code with Simulink either after making it compliant with the Embedded
MATLAB subset or after generating C code.
To learn more about making your M-code compliant with the Embedded
MATLAB subset, see Chapter 3, “Making Your M-Code Compliant with the
Embedded MATLAB Subset”.
To learn more about the tasks for generating C code, see “Tasks For
Generating C Code” on page 2-2.
7-2
Integrating with Simulink®
Introduction
7-3
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
This part of the tutorial demonstrates how to integrate M-code into Simulink
using the Embedded MATLAB Function block. The Embedded MATLAB
Function block allows you to add MATLAB functions to Simulink models
for simulation, testing, code generation, and/or deployment to embedded
processors. It supports a subset of MATLAB commands that generate efficient
C code.
The file emldemo_lms_05.m implements a least mean squares (LMS) filter. The
models emldemo_noise_cancel_01.mdl and emldemo_noise_cancel_02.mdl
use this filter to remove noise from an input signal. For more information, see
“Example: The LMS Filter” on page 2-4.
Note If you have not already copied these files to a local folder, follow the
instructions in “Copying Files Locally” on page 3-4.
a Set your MATLAB current folder to the folder that contains your files for
this tutorial. At the MATLAB command line, enter:
7-4
Integrating with Simulink®
cd folder
where folder is the full path name of the folder containing your files.
See “Viewing and Changing the Current Folder Using the Current
Folder Browser” in the MATLAB Desktop Tools and Development
Environment documentation for more information.
b At the MATLAB command line, type:
emldemo_noise_cancel_01
7-5
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
7-6
Integrating with Simulink®
% Compute LMS:
[ ~, Signal_Out, Weights ] = ...
emldemo_lms_05(Noise_In, Signal_In, Reset, Adapt);
end
Because the LMS function does not use the first output from
emldemo_lms_05, replace this output with the MATLAB ~ operator.
Embedded MATLAB ignores inputs and outputs specified by ~. This syntax
helps avoid confusion in your program code and unnecessary clutter in
your workspace.
Note You can use the eml.extrinsic function to call your M-code. Using
eml.extrinsic enables you to debug your M-code in MATLAB. For more
information, see Using eml.extrinsic to Debug Your M-Code.
7-7
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
input ports to the block and the function outputs Signal_Out and Weights
appear as output ports.
5 Save the model by selecting File > Save from the Embedded MATLAB
editor menu.
7-8
Integrating with Simulink®
From... To...
Settings > Adapt Embedded MATLAB Function Block
> Adapt
Settings > Reset Embedded MATLAB Function Block
> Reset
White Noise Embedded MATLAB Function Block
> Noise_In
Acoustic_Environment > Signal_Out Embedded MATLAB Function Block
> Signal_In
Embedded MATLAB Function Block To Audio Device
> Signal_Out
Embedded MATLAB Function Block Analysis and Visualization > Signal
> Signal_Out
Embedded MATLAB Function Block Analysis and Visualization >
> Weights Weights
7-9
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
2 Select Tools > Edit Data/Ports to open the Ports and Data Manager.
3 Select the signal called Signal_Out from the list in the left pane.
7-10
Integrating with Simulink®
4 On the General tab, change the Sampling mode from Sample based
to Frame based.
5 Close the Ports and Data Manager and the Embedded MATLAB editor.
7-11
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
While the model is running, you can double-click the Reset and Adapt
settings to control the operation of the filter. When Adapt is enabled, the
filter continuously updates the filter weights. When Adapt is disabled, the
filter weights remain at their current values. If Reset is set, the filter
resets the filter weights.
For standard operation, you should enable the Adapt signal and disable
the Reset signal.
As Simulink runs the model, you see and hear outputs. Initially, you hear
the audio signal distorted by noise. Then, during the first few seconds,
the filter attenuates the noise gradually, until you hear only the music
playing with very little noise remaining. MATLAB displays the following
plot showing filter convergence after only a few seconds.
7-12
Integrating with Simulink®
7-13
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
To use eml.extrinsic:
1 Double click the Embedded MATLAB Function block to open the Embedded
MATLAB editor.
% Compute LMS:
[ ~, Signal_Out, Weights ] = ...
emldemo_lms_05(Noise_In, Signal_In, Reset, Adapt);
end
7-14
Integrating with Simulink®
Next Steps
To... See...
Learn more about using the Embedded “Using the Embedded MATLAB Function
MATLAB Function block Block” in the Simulink User’s Guide
Learn more about the best practices used in Chapter 8, “Best Practices for Working with
this tutorial the Embedded MATLAB Subset”
Note To see the complete list of best practices used in this tutorial, see
Chapter 8, “Best Practices for Working with the Embedded MATLAB Subset”.
7-15
7 Integrating Your Embedded MATLAB™ Compliant Code with Simulink®
7-16
8
Note Alternatively, you can use the assert function to define properties
of primary function inputs directly in your M-file. See “Defining Input
Properties Programmatically in the M-File” in the Embedded MATLAB User’s
Guide for more information.
8-2
Recommended Compilation Options for emlmex
the MEX file in accordance with file precedence rules. See “File Precedence”
in MATLAB Programming Fundamentals.
For more information, see “-o Specify Output File Name” in the Embedded
MATLAB Reference.
8-3
8 Best Practices for Working with the Embedded MATLAB™ Subset
For more information and a complete list of compilation options, see emlc in
the Real-Time Workshop Reference.
8-4
Using Build Scripts
close all;
clear all;
clc;
N = 73113;
where:
• close all deletes all figures whose handles are not hidden. See close in
the MATLAB Graphics function reference for more information.
• clear all removes all variables, functions, and MEX-files from memory,
leaving the workspace empty. It also clears all breakpoints.
Note Remove the clear all command from the build scripts if you want
to preserve breakpoints for debugging.
• clc clears all input and output from the Command Window display, giving
you a “clean screen.”
8-5
8 Best Practices for Working with the Embedded MATLAB™ Subset
8-6
Using M-Lint
Using M-Lint
1 From the MATLAB menu, select File > Preferences > M-Lint.
8-7
8 Best Practices for Working with the Embedded MATLAB™ Subset
8-8
Comparing Files
Comparing Files
In this section...
“Comparing Two Versions of a File Using the MATLAB Compare Against
Option” on page 8-9
“Comparing C Code and M-Code Using Tiling in the MATLAB Editor” on
page 8-11
1 Open one of the files you want to compare in the MATLAB Editor.
2 Select Tools > Compare Against > Browse. Navigate to the file you
want to compare against, select the file, and click Open.
The File and Folder Comparison tool opens, displaying the files side by side
and highlighting lines that do not match:
• Pink highlighting and an x at the start of a line indicate that the content
of the lines differs between the two files.
• Green highlighting and a > at the start of a line indicate a line that exists
in the file presented on the right, but not in the file presented on the left.
• Green highlighting and a < at the end of a line indicate a line that exists
in the file presented on the left, but not in the file presented on the right.
8-9
8 Best Practices for Working with the Embedded MATLAB™ Subset
For more information, see “Comparing Files and Folders” in the MATLAB
Desktop Tools and Development Environment documentation.
8-10
Comparing Files
1 Open the C file and the M-file in the Editor. (Dock both windows if they
are not docked.)
2 Select Window > Left/Right Tile (or the toolbar button) to view
the files side by side.
8-11
8 Best Practices for Working with the Embedded MATLAB™ Subset
8-12
Testing MEX Functions in MATLAB®
8-13
8 Best Practices for Working with the Embedded MATLAB™ Subset
8-14
File Naming Conventions
For example, the file naming convention in the Embedded MATLAB getting
started tutorial is:
For example:
8-15
8 Best Practices for Working with the Embedded MATLAB™ Subset
8-16
Index
C
Index getting started tutorial prerequisites 1-8
C compiler integrating compliant code with
set up for Embedded MATLAB 3-4 Simulink 7-2
code generation making code compliant 3-2
converting MATLAB code to embeddable C MEX functions 4-2
code 2-2 recommended compilation options for
emlc 8-4
recommended compilation options for
D emlmex 8-2
design considerations test scripts 4-5
for generating embeddable C code from testing MEX functions 4-5
MATLAB code 2-3 using emlc 5-2
using emlmex 3-6
using M-Lint 3-2
E
when not to use 1-6
elaboration when to use 1-3
Embedded MATLAB code 6-2 Embedded MATLAB compliant code
Embedded MATLAB integrating with Simulink 7-2
benefits of 1-7 embedded MATLAB function block
best practices calling M-code 7-7
comparing files 3-17 4-12 8-9 Embedded MATLAB function block
generate C code only 8-4 using 7-4
generate compilation report 8-3 to 8-4 eml.extrinsic
preserving your code 8-14 using to debug M-code 7-14
separating test bench from function emlc
code 8-8 recommended compilation options 8-4
specifying input properties 3-17 8-2 emlmex
specifying output file name 3-18 8-2 recommended compilation options 8-2
testing MEX functions in MATLAB 8-13
using build scripts 4-12 8-5
using file naming convention 4-12 8-15 G
using M-Lint 8-7 generating code
using test scripts 4-12 converting MATLAB code to embeddable C
C code generation 2-2 code 2-2
C compiler set up 3-4
compliance 3-2
I
description 1-2
elaborating code 6-2 integrating M-code with Simulink
features 1-4 Embedded MATLAB 7-2
generating C code 5-2
Index-1
Index
M T
M-Lint testing
using with Embedded MATLAB 3-2 Embedded MATLAB compliant code 4-5
Index-2