Contenuto principale

La traduzione di questa pagina non è aggiornata. Fai clic qui per vedere l'ultima versione in inglese.

Generazione di codice C/C++ da una funzione di MATLAB

Questo esempio mostra il workflow consigliato per generare codice C/C++ da una funzione di MATLAB®. I passaggi di questo workflow sono:

  1. Preparare il codice MATLAB per la generazione di codice.

  2. Generare e testare la funzione MEX.

  3. Generare ed esaminare il codice C/C++.

Questo esempio genera codice C/C++ dalla riga di comando utilizzando il comando codegen. Per scoprire come generare codice utilizzando l'app MATLAB Coder™, vedere Generate C Code by Using the MATLAB Coder App.

Creazione del codice MATLAB e dei dati di campionamento

Questo passaggio è necessario ai fini dell'esempio e non è un passaggio tipico del workflow di generazione di codice.

Creare una funzione di MATLAB averagingFilterML che agisca come filtro di media su un segnale di input. Questa funzione accetta un vettore di input dei valori del segnale e restituisce un vettore di output dei valori filtrati. Il vettore di output ha le stesse dimensioni del vettore di input. La funzione averagingFilterML utilizza la variabile slider per rappresentare una finestra scorrevole di 16 valori di segnale e calcola il valore medio del segnale per ciascuna posizione della finestra.

type averagingFilterML
function y = averagingFilterML(x)
slider = zeros(16,1);
y = zeros(size(x));
for i = 1:numel(x)
    slider(2:end) = slider(1:end-1); % move one position in the buffer
    slider(1) = x(i); % Add a new sample value to the buffer
    y(i) = sum(slider)/numel(slider); % write the average of the current window to y
end
end

Generare un'onda sinusoidale rumorosa come dati di campionamento e utilizzare averagingFilterML per filtrare i dati rumorosi. Tracciare i dati rumorosi e i dati filtrati nella stessa finestra grafica.

v = 0:0.00614:2*pi;
x = sin(v) + 0.3*rand(1,numel(v));
y = averagingFilterML(x);
plot(x,"red");
hold on
plot(y,"blue");
hold off;

Figure contains an axes object. The axes object contains 2 objects of type line.

Passaggio 1: preparare il codice MATLAB per la generazione di codice

Rinominare la funzione averagingFilterML in averagingFilterCG. Aggiungere la direttiva %#codegen a averagingFilterCG per indicare a MATLAB Code Analyzer di identificare gli avvisi e gli errori specifici della generazione di codice. Per la generazione di codice, è necessario definire i tipi delle variabili di input. Specificare l'input come vettore illimitato di doubles utilizzando un blocco arguments.

type averagingFilterCG
function y = averagingFilterCG(x) %#codegen
arguments
    x (1,:) double
end
slider = zeros(16,1);
y = zeros(size(x));
for i = 1:numel(x)
    slider(2:end) = slider(1:end-1); % move one position in the buffer
    slider(1) = x(i); % Add a new sample value to the buffer
    y(i) = sum(slider)/numel(slider); % write the average of the current window to y
end
end

Passaggio 2: generare e testare la funzione MEX

È importante generare e testare una funzione MEX prima di generare codice C/C++. L'esecuzione della funzione MEX in MATLAB prima della generazione del codice C/C++ consente di rilevare e correggere errori di runtime che sono molto più difficili da diagnosticare nel codice generato. Inoltre, è possibile utilizzare la funzione MEX per verificare che il codice generato funzioni in modo analogo al codice MATLAB originale.

Utilizzare il comando codegen per generare una funzione MEX da averagingFilterCG. Testare la funzione MEX con lo stesso input passato alla funzione originale di MATLAB e confrontare i risultati. La funzione MEX produce lo stesso output.

codegen averagingFilterCG
Code generation successful.
z = averagingFilterCG_mex(x);
plot(x,"red");
hold on
plot(z,"blue");
hold off;

Figure contains an axes object. The axes object contains 2 objects of type line.

Passaggio 3: generare ed esaminare il codice C/C++

Utilizzare il comando codegen con l'opzione -config:lib per generare una libreria C autonoma. Esaminare la funzione averagingFilterCG nel codice C generato.

codegen -config:lib averagingFilterCG
Code generation successful.
type(fullfile("codegen","lib","averagingFilterCG","averagingFilterCG.c"))
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: averagingFilterCG.c
 *
 * MATLAB Coder version            : 25.1
 * C/C++ source code generated on  : 01-Feb-2025 07:27:41
 */

/* Include Files */
#include "averagingFilterCG.h"
#include "averagingFilterCG_emxutil.h"
#include "averagingFilterCG_types.h"
#include <string.h>

/* Function Definitions */
/*
 * Arguments    : const emxArray_real_T *x
 *                emxArray_real_T *y
 * Return Type  : void
 */
void averagingFilterCG(const emxArray_real_T *x, emxArray_real_T *y)
{
  double slider[16];
  double b_slider[15];
  const double *x_data;
  double *y_data;
  int i;
  int k;
  int loop_ub;
  x_data = x->data;
  memset(&slider[0], 0, 16U * sizeof(double));
  loop_ub = y->size[0] * y->size[1];
  y->size[0] = 1;
  y->size[1] = x->size[1];
  emxEnsureCapacity_real_T(y, loop_ub);
  y_data = y->data;
  loop_ub = x->size[1];
  for (i = 0; i < loop_ub; i++) {
    y_data[i] = 0.0;
  }
  loop_ub = x->size[1];
  for (i = 0; i < loop_ub; i++) {
    double b_y;
    memcpy(&b_slider[0], &slider[0], 15U * sizeof(double));
    /*  move one position in the buffer */
    b_y = x_data[i];
    slider[0] = b_y;
    /*  Add a new sample value to the buffer */
    for (k = 0; k < 15; k++) {
      double d;
      d = b_slider[k];
      slider[k + 1] = d;
      b_y += d;
    }
    y_data[i] = b_y / 16.0;
    /*  write the average of the current window to y */
  }
}

/*
 * File trailer for averagingFilterCG.c
 *
 * [EOF]
 */

In alternativa, utilizzare il comando codegen con le opzioni -config:lib e -lang:C++ per generare una libreria C++ autonoma. Confrontare la funzione averagingFilterCG nel codice C++ generato con quella nel codice C generato.

codegen -config:lib -lang:c++ averagingFilterCG
Code generation successful.
type(fullfile("codegen","lib","averagingFilterCG","averagingFilterCG.cpp"))
//
// Prerelease License - for engineering feedback and testing purposes
// only. Not for sale.
// File: averagingFilterCG.cpp
//
// MATLAB Coder version            : 25.1
// C/C++ source code generated on  : 01-Feb-2025 07:27:45
//

// Include Files
#include "averagingFilterCG.h"
#include "coder_array.h"
#include <algorithm>
#include <cstring>

// Function Definitions
//
// Arguments    : const coder::array<double, 2U> &x
//                coder::array<double, 2U> &y
// Return Type  : void
//
void averagingFilterCG(const coder::array<double, 2U> &x,
                       coder::array<double, 2U> &y)
{
  double slider[16];
  double b_slider[15];
  int loop_ub;
  std::memset(&slider[0], 0, 16U * sizeof(double));
  y.set_size(1, x.size(1));
  loop_ub = x.size(1);
  for (int i{0}; i < loop_ub; i++) {
    double b_y;
    y[i] = 0.0;
    std::copy(&slider[0], &slider[15], &b_slider[0]);
    //  move one position in the buffer
    b_y = x[i];
    slider[0] = b_y;
    //  Add a new sample value to the buffer
    for (int k{0}; k < 15; k++) {
      double d;
      d = b_slider[k];
      slider[k + 1] = d;
      b_y += d;
    }
    y[i] = b_y / 16.0;
    //  write the average of the current window to y
  }
}

//
// File trailer for averagingFilterCG.cpp
//
// [EOF]
//

Vedi anche

Argomenti