[Simulink] System Target File學習筆記
Code Generation
System target file
Target Language Compiler 是程式碼生成工具, Simulink Coder/Embedded Coder 會使用這個工具,去執行 .tlc 檔案。 tlc 檔案裡描述瞭如何將 .rtw 變成程式碼。
程式碼生成用到的 .tlc 檔案是一系列,而不是單單是一個或者一類。
%% SYSTLC: STM32F4 Target TMF: ert_default_tmf MAKE: make_rtw EXTMODE: ext_comm %selectfile NULL_FILE %assign CodeFormat = "Embedded-C" %assign TargetType = "RT" %assign Language = "C" %include "codegenentry.tlc" /% BEGIN_RTW_OPTIONS %----------------------------------------% % Configure RTW code generation settings % %----------------------------------------% rtwgensettings.BuildDirSuffix = '_stm32f4'; rtwgensettings.DerivedFrom = 'ert.tlc'; rtwgensettings.Version = '1'; END_RTW_OPTIONS %/
第1行的註釋%% SYSTLC: STM32F4 Target TMF: ert_default_tmf MAKE: make_rtw EXTMODE: ext_comm
對屬性進行了描述,告訴Simulink環境,該系統目標檔案支援哪些功能,這裡支援
- 支援生成mk檔案的tmf模板
- 支援mk的命令
- 支援外部命令
%selectfile NULL_FILE
,要做一個函式級的或非指令碼型別的,寫這句。
%assign CodeFormat = "Embedded-C"
,定義變數,說明支援生成程式碼的型別為嵌入式C程式碼
%assign TargetType = "RT"
%assign Language = "C"
,生成C語言程式碼
另外還有其他的命令,如下:
%assign AutoBuildProcedure = !GenerateSampleERTMain
,不生成模板的ert檔案
這條命令的作用等同於下圖中黃色部分
%include "commontargetlib.tlc"
,將commontargetlib.tlc展開執行
%include "codegenentry.tlc"
,將codegenentry.tlc展開執行
tlc檔案的後半部分為巨集定義,以/% BEGIN_RTW_OPTIONS
/% END_RTW_OPTIONS
結束,定義了使用者選擇該tlc檔案後,Code Generation的設定以及該欄下方的Tab欄顯示內容。
巨集定義
上面的例項中沒有對Tab欄顯示內容做修改,下面的例子(ST公司提供的STM32-MAT-TARGET支援包)給出了新增Tab欄顯示內容的例項:
%% SYSTLC: stm32 (Embedded Target) TMF: stm32.tmf MAKE: make_rtw \
%% EXTMODE: ext_comm
%selectfile NULL_FILE
%%
%% System Target File for stm32
%%
%% $ stm32.tlc 2009-05-14 dlange $
%%
%assign CodeFormat = "Embedded-C"
%assign TargetType = "RT"
%assign Language = "C"
%include "codegenentry.tlc"
/%
BEGIN_RTW_OPTIONS
oIdx = 1;
rtwoptions(oIdx).prompt = 'STM32 Options';
rtwoptions(oIdx).type = 'Category';
rtwoptions(oIdx).enable = 'on';
rtwoptions(oIdx).default = 8;
rtwoptions(oIdx).popupstrings = '';
rtwoptions(oIdx).tlcvariable = '';
rtwoptions(oIdx).tooltip = '';
rtwoptions(oIdx).callback = '';
rtwoptions(oIdx).makevariable = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Download Application';
rtwoptions(oIdx).type = 'Checkbox';
rtwoptions(oIdx).default = 'on';
rtwoptions(oIdx).tlcvariable = 'DownloadApplication';
rtwoptions(oIdx).makevariable = 'DOWNLOADAPPLICATION';
rtwoptions(oIdx).tooltip = ...
['Select to open STM32 generated project.'];
rtwoptions(oIdx).callback = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'STM32CubeMx Path update';
rtwoptions(oIdx).type = 'Checkbox';
rtwoptions(oIdx).default = 'off';
rtwoptions(oIdx).tlcvariable = 'STM32CubeMxPathUpdate';
rtwoptions(oIdx).makevariable = 'STM32CUBEMXPATHUPDATE';
rtwoptions(oIdx).tooltip = ...
['Get STM32CubeMx path from registry. Uncheck to modify path manually.'];
rtwoptions(oIdx).callback = 'stm32cubemxpath_callback(hDlg, hSrc, ''STM32CubeMxPathUpdate'')';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'STM32CubeMx installation path';
rtwoptions(oIdx).type = 'Edit';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'STM32CubeMxPath';
rtwoptions(oIdx).makevariable = 'STM32CUBEMXPATH';
rtwoptions(oIdx).enable = 'on';
rtwoptions(oIdx).tooltip = ...
['installation path for STM32CubeMx'];
rtwoptions(oIdx).callback = 'stm32cubemxpath_callback(hDlg, hSrc, ''STM32CubeMxPath'')';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Installed Path';
rtwoptions(oIdx).type = 'NonUI';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'Target_Inst_path';
rtwoptions(oIdx).makevariable = 'TARGET_INST_PATH';
rtwoptions(oIdx).enable = 'off';
rtwoptions(oIdx).tooltip = '';
rtwoptions(oIdx).callback = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Installed Full Path';
rtwoptions(oIdx).type = 'Edit';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'Target_Inst_Fullpath';
rtwoptions(oIdx).makevariable = 'TARGET_INST_FULLPATH';
rtwoptions(oIdx).enable = 'off';
rtwoptions(oIdx).tooltip = ...
['Path to package added with pathtool command.'];
rtwoptions(oIdx).callback = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Update installed path';
rtwoptions(oIdx).type = 'Pushbutton';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'UpdateInstalledPath';
rtwoptions(oIdx).makevariable = 'UPDATEINSTALLEDPATH';
rtwoptions(oIdx).tooltip = ...
['Click to automatically update package installation path.'];
rtwoptions(oIdx).callback = 'stm32updatepath_callback(hDlg, hSrc)';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Model configuration (ioc) Full Path';
rtwoptions(oIdx).type = 'Edit';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'Ioc_Fullpath';
rtwoptions(oIdx).makevariable = 'IOC_FULLPATH';
rtwoptions(oIdx).enable = '';
rtwoptions(oIdx).tooltip = ...
['Path to ioc configuration file.'];
rtwoptions(oIdx).callback = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Interrupt Handler Optimization';
rtwoptions(oIdx).type = 'Checkbox';
rtwoptions(oIdx).default = 'on';
rtwoptions(oIdx).tlcvariable = 'IT_Handler_Optim';
rtwoptions(oIdx).makevariable = 'IT_HANDLER_OPTIM';
rtwoptions(oIdx).tooltip = ...
['HAL IRQ Handler not generated from STM32CubeMX. Code is not generated in HAL callback function but directly in IRQ Handler. '];
rtwoptions(oIdx).callback = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'STM32 Project Files';
rtwoptions(oIdx).type = 'Category';
rtwoptions(oIdx).enable = 'on';
rtwoptions(oIdx).default = 5;
rtwoptions(oIdx).popupstrings = '';
rtwoptions(oIdx).tlcvariable = '';
rtwoptions(oIdx).tooltip = '';
rtwoptions(oIdx).callback = '';
rtwoptions(oIdx).makevariable = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Append to list';
rtwoptions(oIdx).type = 'Checkbox';
rtwoptions(oIdx).enable = '';
rtwoptions(oIdx).default = 'on';
rtwoptions(oIdx).popupstrings = '';
rtwoptions(oIdx).tlcvariable = 'STM32AppendToList';
rtwoptions(oIdx).makevariable = '';
rtwoptions(oIdx).tooltip = ...
['Files and paths selected will be appended to the list'];
rtwoptions(oIdx).callback = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Select source files (.c)';
rtwoptions(oIdx).type = 'Pushbutton';
rtwoptions(oIdx).enable = '';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).popupstrings = '';
rtwoptions(oIdx).tlcvariable = 'UpdateCFilelist';
rtwoptions(oIdx).makevariable = '';
rtwoptions(oIdx).tooltip = ...
['Click to open multiselect window'];
rtwoptions(oIdx).callback = 'stm32updateCfileList_callback(hDlg, hSrc, ''STM32AppendToList'')';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'C files included to project';
rtwoptions(oIdx).type = 'Edit';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'CProjectFiles';
rtwoptions(oIdx).makevariable = '';
rtwoptions(oIdx).enable = '';
rtwoptions(oIdx).tooltip = ...
['C files include functions that can be called from Simulink MATLAB Function'];
rtwoptions(oIdx).callback = '';
rtwoptions(oIdx).popupstrings = '';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Select include files (.h)';
rtwoptions(oIdx).type = 'Pushbutton';
rtwoptions(oIdx).enable = '';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).popupstrings = '';
rtwoptions(oIdx).tlcvariable = 'UpdateHPathlist';
rtwoptions(oIdx).makevariable = '';
rtwoptions(oIdx).tooltip = ...
['Click to open multiselect window'];
rtwoptions(oIdx).callback = 'stm32updateHPathList_callback(hDlg, hSrc, ''STM32AppendToList'')';
oIdx = oIdx + 1;
rtwoptions(oIdx).prompt = 'Header files added to project';
rtwoptions(oIdx).type = 'Edit';
rtwoptions(oIdx).default = '';
rtwoptions(oIdx).tlcvariable = 'HPathFiles';
rtwoptions(oIdx).makevariable = '';
rtwoptions(oIdx).enable = '';
rtwoptions(oIdx).tooltip = ...
['Header files included for C functions that can be called from Simulink MATLAB Function'];
rtwoptions(oIdx).callback = '';
rtwoptions(oIdx).popupstrings = '';
%----------------------------------------%
% Configure RTW code generation settings %
%----------------------------------------%
rtwgensettings.DerivedFrom = 'ert.tlc';
rtwgensettings.BuildDirSuffix = '_stm32';
rtwgensettings.Version = '1';
rtwgensettings.SelectCallback = ['stm32_SelectCallback(hDlg, hSrc)'];
%rtwgensettings.ActivateCallback = ['stm32_ActivateCallback(hDlg, hSrc)'];
rtwgensettings.PostApplyCallback = ['stm32_PostApplyCallback(hDlg, hSrc)'];
END_RTW_OPTIONS
%/
%% [EOF]: stm32.tlc
程式碼生成配置
/%
BEGIN_RTW_OPTIONS
%----------------------------------------%
% Configure RTW code generation settings %
%----------------------------------------%
rtwgensettings.BuildDirSuffix = '_stm32f4';
rtwgensettings.DerivedFrom = 'ert.tlc';
rtwgensettings.Version = '1';
END_RTW_OPTIONS
%/
rtwgensettings.BuildDirSuffix = '_stm32f4';
設定程式碼生成的資料夾名字
rtwgensettings.DerivedFrom = 'ert.tlc';
繼承ert.tlc的模板
另外,在 % Configure RTW code generation settings %
中還有回撥函式的定義,這裡給出autosar.tlc的例項,具體程式碼段如下:
/%
BEGIN_RTW_OPTIONS
rtwoptions = autosar_rtwoptions_callback('GetOptions', rtwoptions);
rtwgensettings.BuildDirSuffix = '_autosar_rtw';
rtwgensettings.Version = autosarcore.rtwOptions('GetRtwOptionsVersion');
rtwgensettings.SelectCallback = 'autosar_rtwoptions_callback(''SelectCallBack'', hSrc, hDlg)';
rtwgensettings.ActivateCallback = 'autosar_rtwoptions_callback(''ActivateCallBack'', hSrc, hDlg)';
rtwgensettings.DerivedFrom = 'ert.tlc';
END_RTW_OPTIONS
%/
這裡出現了兩個回撥函式
rtwgensettings.SelectCallback = 'autosar_rtwoptions_callback(''SelectCallBack'', hSrc, hDlg)';
rtwgensettings.ActivateCallback = 'autosar_rtwoptions_callback(''ActivateCallBack'', hSrc, hDlg)';
回撥函式格式為:
% 在Code Generation的TLC選擇框內選擇該tlc檔案後執行哪些動作
% 這個callback_handler可以由使用者自行定義
rtwgensettings.SelectCallback =callback_handler(hDlg,hSrc);
rtwgensettings.ActivateCallback = callback_handler(hDlg,hSrc);
rtwgensettings.PostApplyCallback = callback_handler(hDlg,hSrc);
callback_handler例項
callback_handler可以以.m的函式檔案放置到tlc檔案所在路徑下。下面給出一個具體的例項(該例項為SCANeR提供的ert_scanerapi_select.m)
function ert_scanerapi_select(hDlg, hSrc)
slConfigUISetVal(hDlg, hSrc, 'StopTime', 'inf');
slConfigUISetVal(hDlg, hSrc, 'SolverType', 'Fixed-step');
slConfigUISetVal(hDlg, hSrc, 'Solver', 'FixedStepDiscrete');
slConfigUISetVal(hDlg, hSrc, 'SupportContinuousTime', 'on');
slConfigUISetVal(hDlg, hSrc, 'SupportNonInlinedSFcns', 'on');
slConfigUISetVal(hDlg, hSrc, 'GenerateSampleERTMain', 'off');
slConfigUISetEnabled(hDlg, hSrc, 'GenerateSampleERTMain', false);
slConfigUISetVal(hDlg, hSrc, 'ModelReferenceCompliant', 'on');
% slConfigUISetEnabled(hDlg, hSrc, 'ModelReferenceCompliant', false);
其中,hDlg
為configuration parameters的控制代碼,hSrc
為模型的控制代碼,slConfigUISetVal
為Simulink的built-in函式,一共4個引數,前兩個為hDlg
和hSrc
,後面兩個為要設定的引數名
和對應的引數值
,slConfigUISetEnabled
同理,設定enabled用。
【提示】要檢視引數名,在Configuration Parameters的對話方塊內需要檢視的內容處右鍵,what’s This?後檢視,如圖。
點選show more information後可以檢視該引數的具體設定:
如果是針對嵌入式開發,callback_handler中可以將下列命令引入:
function ert_example_select(hDlg, hSrc)
% 設定固定點步長,並禁止修改
slConfigUISetVal(hDlg, hSrc, 'SolverType', 'Fixed-step');
slConfigUISetEnabled(hDlg, hSrc, 'SolverType', 'off');
% 設定離散求解器
slConfigUISetVal(hDlg, hSrc, 'Solver', 'FixedStepDiscrete');
% 設定預設取樣時間
slConfigUISetVal(hDlg, hSrc, 'FixedStep', '0.1');
% 設定內聯引數
% 高版本的MATLAB中這個引數修改為Default parameter behavior ?
slConfigUISetVal(hDlg, hSrc, 'InlineParams', 'on');
% 生成報告
slConfigUISetVal(hDlg, hSrc, 'GenerateReport', 'on');
% 自動開啟報告
slConfigUISetVal(hDlg, hSrc, 'LaunchReport', 'on');
% 只生成程式碼
slConfigUISetVal(hDlg, hSrc, 'GenCodeOnly', 'on');
% 不生成makefile(不生成可執行檔案,不需要makefile檔案)
slConfigUISetVal(hDlg, hSrc, 'GenerateMakefile', 'off');
% 生成註釋
slConfigUISetVal(hDlg, hSrc, 'GenerateComments', 'on');
% 生成A2L檔案
slConfigUISetVal(hDlg, hSrc, 'GenerateASAP2', 'on');
使用for迴圈改寫上面的.m回撥函式:
function ert_example_select_for_loop(hDlg, hSrc)
configs = {'SolverType','on';
'Solver','FixedStepDiscrete';
'FixedStep', '0.1';
'InlineParams', 'on';
'GenerateReport', 'on';
'LaunchReport', 'on';
'GenCodeOnly', 'on';
'GenerateMakefile', 'off';
'GenerateComments', 'on';
'GenerateASAP2', 'on';};
for i = 1:length(configs)
slfConfigUISetVal(hDlg,hSrc,configs{i,1},configs{i,2});
end
slConfigUISetEnabled(hDlg, hSrc, 'SolverType', 'off');
在實際建模時,可以將修改system target file的命令放置到某個config模組的回撥函式中,這樣,只要拖入該模組,就可以實現自動將系統目標檔案修改的目的。
【注意】 下面兩個命令可以在Matlab的command windows中對Simulink模型的system target file進行修改。
disableimplicitsignalresolution(bdroot);
set_param(bdroot,‘SystemTargetFile’,‘ert_example.tlc’)
連結:https://pan.baidu.com/s/1-q1a8Kt4D9SU-AaG-qODIw
提取碼:5aax