Усреднение фильтра

Этот пример показывает рекомендуемый рабочий процесс для генерации кода С от функции MATLAB с помощью команды codegen. Это шаги:

1. Добавьте директиву %#codegen в функцию MATLAB, чтобы указать, что это предназначается для генерации кода. Эта директива также позволяет анализатору кода MATLAB идентифицировать предупреждения и ошибки, характерные для MATLAB для генерации кода.

2. Сгенерируйте MEX-функцию, чтобы проверять, что код MATLAB подходит для генерации кода. Если ошибки происходят, необходимо зафиксировать их прежде, чем сгенерировать код С.

3. Протестируйте MEX-функцию в MATLAB, чтобы гарантировать, что это функционально эквивалентно оригинальному коду MATLAB и что никакие ошибки времени выполнения не происходят.

4. Сгенерируйте код С.

5. Осмотрите код С.

Предпосылки

Нет никаких предпосылок для этого примера.

О функции averaging_filter

Функция 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

Директива компиляции %#codegen указывает, что код MATLAB предназначается для генерации кода.

Создайте некоторые выборочные данные

Сгенерируйте шумную синусоиду и постройте результат.

v = 0:0.00614:2*pi;
x = sin(v) + 0.3*rand(1,numel(v));
plot(x, 'red');

Сгенерируйте MEX-функцию для тестирования

Сгенерируйте MEX-функцию с помощью команды codegen. Команда codegen проверяет, что функция MATLAB подходит для генерации кода и генерирует MEX-функцию, которую можно протестировать в MATLAB до генерации кода С.

codegen averaging_filter -args {x}

Поскольку C использует статический контроль типов, codegen должен определить свойства всех переменных в файлах MATLAB во время компиляции. Здесь, параметр командной строки -args подает входной сигнал в качестве примера так, чтобы codegen мог вывести новые типы на основе входных типов. Используя демонстрационный сигнал, созданный выше, когда, вход в качестве примера гарантирует, что MEX-функция может использовать тот же вход.

По умолчанию codegen генерирует MEX-функцию под названием averaging_filter_mex в текущей папке. Это позволяет вам тестировать код MATLAB и MEX-функцию и сравнивать результаты.

Протестируйте MEX-функцию в MATLAB

Запустите 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}

Осмотрите сгенерированный код

Команда codegen с опцией -config coder.config('lib') генерирует код С, группированный как автономная библиотека C. Сгенерированный код C находится в папке codegen/lib/averaging_filter/. Файлы:

dir codegen/lib/averaging_filter/
.                              averaging_filter_terminate.h   
..                             averaging_filter_terminate.o   
averaging_filter.a             averaging_filter_types.h       
averaging_filter.c             buildInfo.mat                  
averaging_filter.h             codeInfo.mat                   
averaging_filter.o             codedescriptor.dmr             
averaging_filter_initialize.c  examples                       
averaging_filter_initialize.h  interface                      
averaging_filter_initialize.o  rtw_proj.tmw                   
averaging_filter_ref.rsp       rtwtypes.h                     
averaging_filter_rtw.mk        
averaging_filter_terminate.c   

Осмотрите код С для функции averaging_filter.c

type codegen/lib/averaging_filter/averaging_filter.c
/*
 * File: averaging_filter.c
 *
 * MATLAB Coder version            : 4.2
 * C/C++ source code generated on  : 21-Feb-2019 17:59:38
 */

/* Include Files */
#include <string.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[i];

    /*  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 += dv0[k];
    }

    y[i] = 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]
 */