MATLAB课程:代码示例之C Code Generation(一)
Averaging Filter
This example shows the recommended workflow for generating C code from a MATLAB function using the 'codegen' command. These are the steps: 1. Add the %#codegen directive to the MATLAB function to indicate that it is intended for code generation. This directive also enables the MATLAB code analyzer to identify warnings and errors specific to MATLAB for code generation.
2. Generate a MEX function to check that the MATLAB code is suitable for code generation. If errors occur, you should fix them before generating C code.
3. Test the MEX function in MATLAB to ensure that it is functionally equivalent to the original MATLAB code and that no run-time errors occur.
4. Generate C code.
5. Inspect the C code.
PrerequisitesThere are no prerequisites for this example.
Create a New Folder and Copy Relevant FilesThe following code will create a folder in your current working folder (pwd). The new folder will only contain the files that are relevant for this example. If you do not want to affect the current folder (or if you cannot generate files in this folder), you should change your working folder.
Run Command: Create a New Folder and Copy Relevant Filescoderdemo_setup('coderdemo_averaging_filter');
About the 'averaging_filter' FunctionThe averaging_filter.m function acts as an averaging filter on the input signal; it takes an input vector of values and computes an average for each value in the vector. The output vector is the same size and shape as the input vector.
type averaging_filter
% y = averaging_filter(x)% Take an input vector signal 'x' and produce an output vector signal 'y' with% same type and shape as 'x' but filtered.function y = averaging_filter(x) %#codegen% Use a persistent variable 'buffer' that represents a sliding window of% 16 samples at a time.persistent buffer;if isempty(buffer) buffer = zeros(16,1);endy = zeros(size(x), class(x));for i = 1:numel(x) % Scroll the buffer buffer(2:end) = buffer(1:end-1); % Add a new sample value to the buffer buffer(1) = x(i); % Compute the current average value of the window and % write result y(i) = sum(buffer)/numel(buffer);end
The %#codegen compilation directive indicates that the MATLAB code is intended for code generation.
Create some Sample DataGenerate a noisy sine wave and plot the result.
v = 0:0.00614:2*pi;x = sin(v) + 0.3*rand(1,numel(v));plot(x, 'red');

Generate a MEX Function for TestingGenerate a MEX function using the 'codegen' command. The 'codegen' command checks that the MATLAB function is suitable for code generation and generates a MEX function that you can test in MATLAB prior to generating C code.
codegen averaging_filter -args {x}
Because C uses static typing, 'codegen' must determine the properties of all variables in the MATLAB files at compile time. Here, the '-args' command-line option supplies an example input so that 'codegen' can infer new types based on the input types. Using the sample signal created above as the example input ensures that the MEX function can use the same input.
By default, 'codegen' generates a MEX function named 'averaging_filter_mex' in the current folder. This allows you to test the MATLAB code and MEX function and compare the results.
Test the MEX Function in MATLABRun the MEX function in MATLAB
y = averaging_filter_mex(x);% Plot the result when the MEX function is applied to the noisy sine wave.% The 'hold on' command ensures that the plot uses the same figure window as% the previous plot command.hold on;plot(y, 'blue');

Generate C Codecodegen -config coder.config('lib') averaging_filter -args {x}
Inspect the Generated CodeThe 'codegen' command with the '-config coder.config('lib')' option generates C code packaged as a standalone C library. The generated C code is in the 'codegen/lib/averaging_filter/' folder. The files are:
dir codegen/lib/averaging_filter/
. codeInfo.mat .. examples averaging_filter.a interface averaging_filter.c rtGetInf.c averaging_filter.h rtGetInf.h averaging_filter.o rtGetInf.o averaging_filter_initialize.c rtGetNaN.c averaging_filter_initialize.h rtGetNaN.h averaging_filter_initialize.o rtGetNaN.o averaging_filter_ref.rsp rt_nonfinite.c averaging_filter_rtw.mk rt_nonfinite.h averaging_filter_terminate.c rt_nonfinite.o averaging_filter_terminate.h rtw_proj.tmw averaging_filter_terminate.o rtwtypes.h averaging_filter_types.h buildInfo.mat
Inspect the C Code for the 'averaging_filter.c' Functiontype codegen/lib/averaging_filter/averaging_filter.c
/* * File: averaging_filter.c * * MATLAB Coder version : 3.1 * C/C++ source code generated on : 07-Jan-2016 17:22:22 *//* Include Files */#include "rt_nonfinite.h"#include "averaging_filter.h"/* Variable Definitions */static double buffer[16];/* Function Definitions *//* * Use a persistent variable 'buffer' that represents a sliding window of * 16 samples at a time. * Arguments : const double x[1024] * double y[1024] * Return Type : void */void averaging_filter(const double x[1024], double y[1024]){ int i; double dv0[15]; double b_y; int k; /* y = averaging_filter(x) */ /* Take an input vector signal 'x' and produce an output vector signal 'y' with */ /* same type and shape as 'x' but filtered. */ for (i = 0; i < 1024; i++) { /* Scroll the buffer */ memcpy(&dv0[0], &buffer[0], 15U * sizeof(double)); /* Add a new sample value to the buffer */ buffer[0] = x; /* Compute the current average value of the window and */ /* write result */ b_y = buffer[0]; for (k = 0; k < 15; k++) { buffer[1 + k] = dv0[k]; b_y += buffer[k + 1]; } y = b_y / 16.0; }}/* * Arguments : void * Return Type : void */void averaging_filter_init(void){ memset(&buffer[0], 0, sizeof(double) << 4);}/* * File trailer for averaging_filter.c * * [EOF] */
CleanupRemove files and return to original folder
Run Command: Cleanupcleanup