이 페이지는 기계 번역을 사용하여 번역되었습니다. 영어 원문을 보려면 여기를 클릭하십시오.
조건부 포함 (#if / #endif)
모델에 변형을 구현함으로써 코드 내에서 전처리기 조건부 지시문을 생성할 수 있습니다. 생성된 코드에서, 전처리기 조건부 지시문은 컴파일 시점에 실행할 코드 부분을 선택합니다.
이 예제에서는 Simulink.Variant 객체를 사용하여 Variant Subsystem 블록을 제어합니다. 변형을 제어하는 다른 방법에 대한 정보는 Variant Control Modes in Variant Blocks를 참조하십시오. Variant Subsystem 블록 이외의 변이 유형에 대한 정보는 Simulink Variants Overview를 참조하십시오.
모델 검사
예제 모델 PreprocessorConditionalsUsingVariantSubsystem를 엽니다.
model = 'PreprocessorConditionalsUsingVariantSubsystem';
open_system(model);
이 모델에는 LeftController와 RightController라는 두 가지 Variant SubSystem이 포함되어 있으며, 각 서브시스템에는 Linear와 Nonlinear라는 두 개의 하위 서브시스템이 있습니다. 모델의 PostLoadFcn 콜백 함수는 rtwdemo_preprocessor_data.mat를 불러옵니다. 콜백 함수를 보려면 Simulink 툴스트립에서 모델링 탭을 클릭한 다음, 설정 섹션에서 모델 설정 > 모델 속성을 클릭하십시오. '모델 속성' 대화 상자에서 콜백 탭을 열고 PostLoadFcn을 선택합니다. 또는 프로그래밍 방식으로 콜백 함수를 확인합니다.
get_param(model,'PostLoadFcn')ans = 'load preprocessor_data.mat'
이 콜백 함수는 Simulink.Variant 객체 두 개(LINEAR와 NONLINEAR)와 Simulink.Parameter, VSSMODE 객체 하나씩을 생성합니다. VSSMODE가 0와 같을 때 LINEAR 변형이 활성화됩니다. VSSMODE가 1와 같을 때 NONLINEAR 변형이 활성화됩니다. VSSMODE는 1로 초기화됩니다. 이 설정들을 프로그래밍 방식으로 확인하십시오.
LINEAR.Condition
ans = 'VSSMODE==0'
NONLINEAR.Condition
ans = 'VSSMODE==1'
VSSMODE.Value
ans = int32
1
LeftController와 RightController는 각각의 Linear 및 Nonlinear 서브시스템에 대한 변형 제어 표현식으로 LINEAR와 NONLINEAR를 사용합니다. 이 구성을 보려면 LeftController를 마우스 오른쪽 버튼으로 클릭한 다음, [블록 파라미터]
버튼을 클릭하십시오. 또는 프로그래밍 방식으로 변형 제어 표현식을 확인하십시오.
choices = get_param(append(model,'/LeftController'),'VariantChoices'); choices(1)
ans = struct with fields:
Name: 'LINEAR'
BlockName: 'PreprocessorConditionalsUsingVariantSubsystem/LeftController/Linear'
choices(2)
ans = struct with fields:
Name: 'NONLINEAR'
BlockName: 'PreprocessorConditionalsUsingVariantSubsystem/LeftController/Nonlinear'
모델 구성하기
구성 파라미터 대화 상자를 엽니다. 왼쪽 창에서 코드 생성을 클릭한 다음, 시스템 타깃 파일이 ert.tlc로 설정되어 있는지 확인하십시오. 또는 프로그래밍 방식으로 파라미터를 설정할 수도 있습니다.
set_param(model,'SystemTargetFile','ert.tlc');
왼쪽 창에서 인터페이스를 클릭합니다. Ignore custom storage classes 파라미터가 해제되어 있는지 확인하십시오. 또는 코딩을 통해 파라미터를 지우십시오.
set_param(model,'IgnoreCustomStorageClasses','off');
전처리기 조건문을 생성하려면 사용자 지정 스토리지 클래스를 사용하십시오.
LeftController 서브시스템에 대한 ‘블록 파라미터’ 대화 상자를 엽니다. Variant activation time 파라미터가 code compile로 설정되어 있는지 확인하십시오. 또는 프로그래밍 방식으로 파라미터를 설정할 수도 있습니다.
set_param(append(model,'/LeftController'),'VariantActivationTime','code compile');
LeftController 서브시스템을 엽니다. 각 서브시스템에 대해 해당 서브시스템을 클릭한 다음, Subsystem Block 탭에서 Atomic Subsystem이 선택되어 있는지 확인하십시오. 또는 프로그래밍 방식으로 파라미터를 설정할 수도 있습니다.
set_param(append(model,'/LeftController/Linear'),'TreatAsAtomicUnit','on'); set_param(append(model,'/LeftController/Nonlinear'),'TreatAsAtomicUnit','on');
코드를 생성합니다.
slbuild(model);
### Searching for referenced models in model 'PreprocessorConditionalsUsingVariantSubsystem'. ### Total of 1 models to build. ### Starting build procedure for: PreprocessorConditionalsUsingVariantSubsystem ### Successful completion of build procedure for: PreprocessorConditionalsUsingVariantSubsystem Build Summary Top model targets: Model Build Reason Status Build Duration ================================================================================================================================================ PreprocessorConditionalsUsingVariantSubsystem Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 19.376s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 21.752s
생성된 코드를 확인합니다. 코드 생성 과정에서 생성된 코드에는 #if 및 #endif 전처리기 지시어가 포함되어 있으며, 이 지시어들은 LINEAR와 NONLINEAR를 사용하여 컴파일할 변형을 하나 선택합니다.
cfile = fullfile('PreprocessorConditionalsUsingVariantSubsystem_ert_rtw','PreprocessorConditionalsUsingVariantSubsystem.c'); coder.example.extractLines(cfile," /* Outputs for Atomic SubSystem: '<Root>/LeftController' */",... " /* End of Outputs for SubSystem: '<Root>/LeftController' */", 1, 1);
/* Outputs for Atomic SubSystem: '<Root>/LeftController' */
#if LINEAR
/* Outputs for Atomic SubSystem: '<S1>/Linear' */
/* VariantMerge generated from: '<S1>/Out1' incorporates:
* DiscreteFilter: '<S3>/Discrete Filter'
*/
rtY.Out1 = rtb_Add - 0.5 * rtDWork.DiscreteFilter_states_a;
/* Update for DiscreteFilter: '<S3>/Discrete Filter' */
rtDWork.DiscreteFilter_states_a = rtY.Out1;
/* End of Outputs for SubSystem: '<S1>/Linear' */
#elif NONLINEAR
/* Outputs for Atomic SubSystem: '<S1>/Nonlinear' */
/* VariantMerge generated from: '<S1>/Out1' incorporates:
* DiscreteFilter: '<S4>/Discrete Filter'
* Lookup_n-D: '<S4>/Lookup Table'
* Sum: '<Root>/Add'
*/
rtY.Out1 = look1_binlxpw(rtb_Add, rtCP_LookupTable_bp01Data,
rtCP_LookupTable_tableData, 4U) - 0.5 * rtDWork.DiscreteFilter_states_o;
/* Update for DiscreteFilter: '<S4>/Discrete Filter' */
rtDWork.DiscreteFilter_states_o = rtY.Out1;
/* End of Outputs for SubSystem: '<S1>/Nonlinear' */
#endif
/* End of Outputs for SubSystem: '<Root>/LeftController' */