MATLAB 함수에서 C/C++ 코드 생성하기
이 예제에서는 MATLAB® 함수에서 C/C++ 코드를 생성하는 데 권장되는 워크플로를 보여줍니다. 이 워크플로의 단계는 다음과 같습니다.
코드 생성을 위해 MATLAB 코드를 준비합니다.
MEX 함수를 생성하고 테스트합니다.
C/C++ 코드를 생성하고 검사합니다.
이 예제에서는 codegen
명령을 사용하여 명령줄에서 C/C++ 코드를 생성합니다. MATLAB Coder 앱을 사용하여 코드를 생성하는 방법은 Generate C Code by Using the MATLAB Coder App 항목을 참조하십시오.
MATLAB 코드 및 샘플 데이터 생성하기
이 단계는 다음 예제에 필요한 것으로, 코드 생성 워크플로에서의 일반적인 단계는 아닙니다.
입력 신호에 대한 평균 필터 역할을 하는 MATLAB 함수 averagingFilterML
을 만듭니다. 이 함수는 신호 값으로 구성된 입력 벡터를 받아 필터링된 값으로 구성된 출력 벡터를 반환합니다. 출력 벡터는 입력 벡터와 크기가 동일합니다. averagingFilterML
함수는 변수 slider
를 사용하여 16개 신호 값의 슬라이딩 윈도우를 나타내고 각 윈도우 위치에 대한 평균 신호 값을 계산합니다.
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
잡음 있는 사인파를 샘플 데이터로 생성하고 averagingFilterML
을 사용하여 잡음 있는 데이터를 필터링합니다. 동일한 Figure 창에 잡음 있는 데이터와 필터링된 데이터를 플로팅합니다.
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;
1단계: 코드 생성을 위한 MATLAB 코드 준비
averagingFilterML
함수의 이름을 averagingFilterCG
로 바꿉니다. MATLAB 코드 분석기가 코드 생성과 관련된 경고 및 오류를 식별하도록 하려면 averagingFilterCG
에 %#codegen
지시문을 추가합니다. 코드 생성 시 입력 변수 유형을 정의해야 합니다. arguments
블록을 사용하여 제한이 없는 doubles
형 벡터로 입력값을 지정합니다.
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
2단계: MEX 함수 생성 및 테스트
C/C++ 코드를 생성하기 전에 MEX 함수를 생성하고 테스트하는 것이 중요합니다. C/C++ 코드를 생성하기 전에 MATLAB에서 MEX 함수를 실행하면 생성 코드에서 진단하기 훨씬 어려운 런타임 오류를 감지하고 수정할 수 있습니다. 또한 MEX 함수를 사용하여 생성 코드가 원래 MATLAB 코드와 유사하게 작동하는지 확인할 수 있습니다.
codegen
명령을 사용하여 averagingFilterCG
에서 MEX 함수를 생성합니다. 원래 MATLAB 함수에 전달한 것과 동일한 입력값으로 MEX 함수를 테스트하고 결과를 비교합니다. MEX 함수는 동일한 출력값을 생성합니다.
codegen averagingFilterCG
Code generation successful.
z = averagingFilterCG_mex(x); plot(x,"red"); hold on plot(z,"blue"); hold off;
3단계: C/C++ 코드 생성 및 검사
-config:lib
옵션과 함께 codegen
명령을 사용하여 독립형 C 라이브러리를 생성합니다. 생성된 C 코드의 averagingFilterCG
함수를 검사합니다.
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 : 24.2 * C/C++ source code generated on : 20-Jul-2024 12:20:51 */ /* 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)); i = y->size[0] * y->size[1]; y->size[0] = 1; y->size[1] = x->size[1]; emxEnsureCapacity_real_T(y, i); y_data = y->data; loop_ub = x->size[1]; for (i = 0; i < loop_ub; i++) { y_data[i] = 0.0; } i = x->size[1]; for (loop_ub = 0; loop_ub < i; loop_ub++) { double b_y; memcpy(&b_slider[0], &slider[0], 15U * sizeof(double)); /* move one position in the buffer */ b_y = x_data[loop_ub]; 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[loop_ub] = b_y / 16.0; /* write the average of the current window to y */ } } /* * File trailer for averagingFilterCG.c * * [EOF] */
또는 -config:lib
및 -lang:C++
옵션과 함께 codegen
명령을 사용하여 독립형 C++ 라이브러리를 생성할 수도 있습니다. 생성된 C++ 코드의 averagingFilterCG
함수와 생성된 C 코드의 함수를 비교합니다.
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 : 24.2 // C/C++ source code generated on : 20-Jul-2024 12:20:55 // // 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 i; int loop_ub; std::memset(&slider[0], 0, 16U * sizeof(double)); y.set_size(1, x.size(1)); loop_ub = x.size(1); for (i = 0; i < loop_ub; i++) { y[i] = 0.0; } i = x.size(1); for (loop_ub = 0; loop_ub < i; loop_ub++) { double b_y; std::copy(&slider[0], &slider[15], &b_slider[0]); // move one position in the buffer b_y = x[loop_ub]; 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[loop_ub] = b_y / 16.0; // write the average of the current window to y } } // // File trailer for averagingFilterCG.cpp // // [EOF] //