주요 콘텐츠

이 페이지는 기계 번역을 사용하여 번역되었습니다. 영어 원문을 보려면 여기를 클릭하십시오.

S-Function 인라인 처리

S-Function 인라인 처리

S-Function을 인라인 처리한다는 것은, 시뮬레이션 중에 사용되었던 C, C++, Fortran 또는 MATLAB® 언어 버전의 블록을 대체할 S-Function 블록용 TLC 파일을 제공하는 것을 의미합니다.

비인라인 S-Function

인라인 처리를 위한 TLC 파일이 제공되지 않는 경우, 대부분의 타깃은 해당 블록에 대한 C MEX S-Function을 재컴파일하여 블록을 지원합니다. C/C++로 작성된 S-Function을 사용하면 메모리 사용량과 속도 측면에서 오버헤드가 발생하며, 코드 생성기 환경에서는 제한된 일부 mx* API 호출만 지원됩니다. 가장 효율적인 생성 코드를 얻으려면, S-Function에 대한 TLC 파일을 작성하여 해당 함수들을 인라인으로 처리해야 합니다.

시뮬레이션에서 S-Function 블록의 함수 중 하나를 실행해야 할 경우, 해당 함수에 대한 MEX 파일을 호출합니다. 코드 생성기가 인라인 처리되지 않은 S-Function을 실행할 때도, 이 다이어그램에서 보여 주듯이 이와 유사한 방식으로 실행됩니다.

인라인 처리의 유형

인라인 처리를 두 가지 범주로 구분해 두면 도움이 됩니다:

  • 완전 인라인 S-Function

  • 래퍼 인라인 S-Function

두 방법 모두 S-Function을 인라인 처리하고, 인라인 처리되지 않은 S-Function으로 인한 오버헤드를 제거하지만, 두 접근 방식은 서로 다릅니다. 아래의 첫 번째 예제인 timestwo.tlc는 완전히 인라인 처리된 TLC 파일로 간주되며, 이 블록의 전체 구현 내용이 해당 블록의 TLC 파일에 포함되어 있습니다.

두 번째 예제에서는 래퍼 TLC 파일을 사용합니다. 이 예제에서는 알고리즘 코드를 직접 생성하는 대신, 코드 본문이 포함된 C 함수를 호출합니다. 래퍼 TLC 파일을 사용하면 다음과 같은 몇 가지 잠재적 이점이 있습니다.

  • C MEX S-Function과 생성된 코드가 C 코드를 공유할 수 있는 방법을 제공합니다. 코드를 두 번 작성할 필요가 없습니다.

  • 호출되는 C 함수가 최적화된 루틴입니다.

  • 모델 내에 여러 개의 블록이 존재할 수 있으며, 각 블록이 동일한 알고리즘 코드를 직접 작성하는 것보다 함수를 호출하도록 하는 것이 코드 크기 측면에서 더 효율적입니다.

  • 기존 C 코드를 생성된 코드에 원활하게 통합할 수 있는 방법을 제공합니다.

완전히 인라인 처리된 S-Function 예제

S-Function을 인라인 처리하면 S-Function 블록의 코드를 모델의 생성된 코드에 직접 삽입할 수 있는 메커니즘을 제공합니다. 함수 포인터를 통해 별도의 소스 파일을 호출하고 이를 위해 별도의 데이터 구조(SimStruct)를 유지하는 대신, 다음 그림에서 볼 수 있듯이 코드가 “인라인”으로 처리되어 있습니다.

S-Function timestwo.c는 완전히 인라인 처리된 S-Function의 간단한 예시를 보여줍니다. 이 블록은 입력값에 2를 곱한 후 그 결과를 출력합니다. 이 블록의 C MEX 버전은 matlabroot/toolbox/simulink/sfuntemplates/src/timestwo.c 파일에 있으며, 이 블록에 대한 인라인 처리용 TLC 파일은 matlabroot/toolbox/simulink/sfuntemplates/tlc_c/timestwo.tlc입니다.

timestwo.tlc

%implements "timestwo" "C"

%% Function: Outputs ==========================================
%%
%function Outputs(block, system) Output
  /* %<Type> Block: %<Name> */
  %%
  /* Multiply input by two */
  %assign rollVars = ["U", "Y"]
  %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
    %<LibBlockOutputSignal(0, "", lcv, idx)> = \
    %<LibBlockInputSignal(0, "", lcv, idx)> * 2.0;
  %endroll
%endfunction

TLC 블록 분석

%implements 지시문은 TLC 블록 파일에서 필수로 사용되며, Target Language Compiler가 블록 유형과 해당 블록이 지원하는 언어를 확인하는 데 사용됩니다. %function 지시문은 함수 선언을 시작하며, 함수 이름인 Outputs와 이 함수에 전달된 인수인 blocksystem를 표시합니다. 다음은 이 블록 인스턴스에 대한 model.rtw 파일의 관련 기록입니다.

프로토타입의 마지막 조각은 Output입니다. 즉, TLC 지시문이 아닌 모든 줄은 이 함수를 통해 TLC에서 현재 선택된 파일에 출력됩니다. 따라서 Outputs 함수 내의 지시문이 아닌 라인들은 해당 블록에 대한 생성 코드가 됩니다.

이 TLC 블록 예제에서 가장 복잡한 부분은 %roll 지시문입니다. TLC는 이 지시문을 사용하여 입력/출력 폭과 입력 데이터가 메모리 상에서 연속적으로 배치되어 있는지 여부에 따라 for 루프를 자동으로 생성합니다. 이 예제에서는 롤(roll) 본문 내에서 출력과 입력에 접근하는 일반적인 방식을 사용하며, LibBlockOutputSignalLibBlockInputSignal를 사용하여 출력과 입력에 접근하고 곱셈 및 할당 연산을 수행합니다. 이 TLC 파일은 유효한 모든 신호 폭을 지원한다는 점에 유의하십시오.

이 블록을 구현하는 데 사용된 유일한 함수는 Outputs입니다. 더 복잡한 블록의 경우, 다른 함수들도 선언되어 있습니다. 더 복잡한 TLC 파일 인라인 처리 예시는 matlabroot/toolbox/simulink/sfuntemplates/tlc_c (열기) 및 matlabroot/toolbox/simulink/blocks/tlc_c (열기) 폴더에서 확인할 수 있으며, matlabroot/rtw/c/tlc/blocks (열기) 폴더에 있는 내장 블록의 소스 코드를 살펴보아도 확인할 수 있습니다.

timestwo 모델

이 간단한 모델은 timestwo S-Function을 사용하며, 인라인 처리된 S-Function 코드가 포함된 생성된 model.c 파일의 MdlOutputs 함수를 보여줍니다.

모델 출력 코드

/* Model output function */
static void timestwo_ex_output(int_T tid)
{

  /* S-Function Block: <Root>/S-Function */
  /* Multiply input by two */
  timestwo_ex_B.timestwo_output = timestwo_ex_P.Constant_Value 
	 * 2.0;

  /* Outport: '<Root>/Out1' */
  timestwo_ex_Y.Out1 = timestwo_ex_B.timestwo_output;
}

래퍼 인라인 S-Function 예제

다음 다이어그램은 S-Function을 래퍼로 인라인 처리하는 방법을 보여줍니다. 이 알고리즘은 생성된 모델 코드에서 직접 호출되므로, S-Function의 오버헤드는 제거되지만 사용자 함수는 그대로 유지됩니다.

이 파일은 timestwo 블록의 래퍼 버전에 대한 인라인 TLC 파일입니다.

%implements "timestwo" "C"

%% Function: BlockTypeSetup ==================================
%%
%function BlockTypeSetup(block, system) void
  %% Add function prototype to model's header file
  %<LibCacheFunctionPrototype...
   ("extern void mytimestwo(real_T* in,real_T* out,int_T els);")>
  %% Add file that contains "myfile" to list of files to be compiled
  %<LibAddToModelSources("myfile")>
%endfunction

%% Function: Outputs ==========================================
%%
%function Outputs(block, system) Output
  /* %<Type> Block: %<Name> */
  %assign outPtr = LibBlockOutputSignalAddr(0, "", "", 0)
  %assign inPtr = LibBlockInputSignalAddr(0, "", "",0)
  %assign numEls = LibBlockOutputSignalWidth(0)
  /* Multiply input by two */
  mytimestwo(%<inPtr>,%<outPtr>,%<numEls>);
  
%endfunction

분석

BlockTypeSetup 함수는 모델 내의 각 블록 유형에 대해 한 번씩 호출되며, Outputs 함수와 달리 직접적인 출력을 생성하지는 않습니다. BlockTypeSetup를 사용하여 model.h 파일에 함수 프로토타입을 포함시키고, 빌드 프로세스에 추가 파일인 myfile.c를 컴파일하도록 지시합니다.

곱셈을 직접 수행하는 대신, Outputs 함수는 이제 mytimestwo 함수를 호출합니다. 모델 내의 이 블록의 모든 인스턴스는 곱셈 연산을 수행하기 위해 동일한 함수를 호출합니다. 그 결과로 도출된 모델 함수인 MdlOutputs는 다음과 같이 됩니다.

static void timestwo_ex_output(int_T tid)
{
  /* S-Function Block: <Root>/S-Function */
  /* Multiply input by two */
  mytimestwo(&model_B.Constant_Value,&model_B.S_Function,1);

  /* Outport Block: <Root>/Out1 */
model_Y.Out1 = model_B.S_Function;
}

참고 항목

도움말 항목