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
,定義變量,說明支援生成代碼的類型為嵌入式C代碼%assign CodeFormat = "Embedded-C"
,生成代碼的目标類型為實時硬體%assign TargetType = "RT"
,生成C語言代碼%assign Language = "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