В этом примере показан рекомендуемый рабочий процесс генерации кода С из функции MATLAB ® с помощью codegen
команда. Вот следующие шаги:
1. Добавьте %#codegen
директива на функцию MATLAB, чтобы указать, что она предназначена для генерации кода. Эта директива также позволяет анализатору кода MATLAB идентифицировать предупреждения и ошибки, характерные для MATLAB для генерации кода.
2. Сгенерируйте MEX-функцию, чтобы проверить, что код MATLAB подходит для генерации кода. Если возникают ошибки, необходимо исправить их перед генерацией кода С
3. Протестируйте MEX-функцию в MATLAB, чтобы убедиться, что она функционально эквивалентна оригинальному коду MATLAB и что никаких ошибок времени выполнения не происходит.
4. Сгенерируйте код С
5. Проверьте код С
Для этого примера нет необходимых условий.
averaging_filter
ФункцияThe averaging_filter.m
функция действует как фильтр усреднения входного сигнала; он принимает вектор входа значений и вычисляет среднее значение для каждого значения в векторе. Вектор выхода имеет тот же размер и форму, что и вектор входа.
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); end y = 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
директива компиляции указывает, что код MATLAB предназначен для генерации кода.
Сгенерируйте шумную синусоиду и постройте график результата.
v = 0:0.00614:2*pi;
x = sin(v) + 0.3*rand(1,numel(v));
plot(x, 'red');
Сгенерируйте MEX-функцию с помощью codegen
команда. The codegen
команда проверяет, что функция MATLAB подходит для генерации кода, и генерирует MEX-функцию, которую можно протестировать в MATLAB до генерации кода С
codegen averaging_filter -args {x}
Code generation successful.
Поскольку на C используется статическое типирование, codegen
необходимо определить свойства всех переменных в файлах MATLAB во время компиляции. Вот, -args
опция командной строки предоставляет пример входа, так что codegen
можно вывести новые типы на основе типов входа. Использование сигнала расчета, созданного выше, в качестве примера входа гарантирует, что MEX-функция может использовать тот же вход.
По умолчанию codegen
генерирует MEX-функцию с именем averaging_filter_mex
в текущей папке. Это позволяет вам протестировать код MATLAB и MEX-функцию и сравнить результаты.
Запуск MEX-функции в 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');
codegen -config coder.config('lib') averaging_filter -args {x}
Code generation successful.
The codegen
команда со -config coder.config('lib')
опция генерирует код С, упакованный как автономная библиотека C. Сгенерированный код C находится в codegen/lib/averaging_filter/
папка. Файлы:
dir codegen/lib/averaging_filter/
. averaging_filter_terminate.c .. averaging_filter_terminate.h .gitignore averaging_filter_terminate.o _clang-format averaging_filter_types.h averaging_filter.a buildInfo.mat averaging_filter.c codeInfo.mat averaging_filter.h codedescriptor.dmr averaging_filter.o compileInfo.mat averaging_filter_data.c defines.txt averaging_filter_data.h examples averaging_filter_data.o interface averaging_filter_initialize.c rtw_proj.tmw averaging_filter_initialize.h rtwtypes.h averaging_filter_initialize.o averaging_filter_rtw.mk
averaging_filter.c
Функцияtype codegen/lib/averaging_filter/averaging_filter.c
/* * File: averaging_filter.c * * MATLAB Coder version : 5.2 * C/C++ source code generated on : 21-Apr-2021 01:20:09 */ /* Include Files */ #include "averaging_filter.h" #include "averaging_filter_data.h" #include "averaging_filter_initialize.h" #include <string.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]) { double dv[15]; double b_y; double d; int i; int k; if (!isInitialized_averaging_filter) { averaging_filter_initialize(); } /* 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(&dv[0], &buffer[0], 15U * sizeof(double)); /* Add a new sample value to the buffer */ buffer[0] = x[i]; /* Compute the current average value of the window and */ /* write result */ b_y = buffer[0]; for (k = 0; k < 15; k++) { d = dv[k]; buffer[k + 1] = d; b_y += d; } y[i] = b_y / 16.0; } } /* * Use a persistent variable 'buffer' that represents a sliding window of * 16 samples at a time. * * Arguments : void * Return Type : void */ void averaging_filter_init(void) { memset(&buffer[0], 0, 16U * sizeof(double)); } /* * File trailer for averaging_filter.c * * [EOF] */