matlab 生成信号文件,生成的代码如何存储内部信号、状态和参数数据
瀏覽模型示例
打開模型示例 rtwdemo_roll。
open_system('rtwdemo_roll')
該模型包含不連接到根級別 Inport 或 Outport 模塊的內部信號。某些信號具有名稱,例如 phiCmd 信號。
該模型還包含一些維護狀態數據的模塊。例如,在 BasicRollMode 子系統中,標記為 Integrator 的 Discrete-Time Integrator 模塊用于維護狀態。
在模型中,將 Configuration Parameters > Code Generation > System target file 設置為 grt.tlc。
set_param('rtwdemo_roll','SystemTargetFile','grt.tlc')
檢查 Configuration Parameters > Code Generation > Interface > Code interface packaging 的設置。設置 Nonreusable function 表示生成的代碼不可重用(可重入)。
對于此示例,通過清除 Configuration Parameters > Code Generation > Interface > Advanced parameters > Mat-file logging 生成更簡單的代碼。
set_param('rtwdemo_roll','MatFileLogging','off')
生成不可重用的代碼
設置以下配置參數:
將 Default parameter behavior 設置為 Tunable。
清除 Signal storage reuse。
set_param('rtwdemo_roll','DefaultParameterBehavior','Tunable',...
'OptimizeBlockIOStorage','off')
從模型中生成代碼。
rtwbuild('rtwdemo_roll')
### Starting build procedure for: rtwdemo_roll
### Successful completion of build procedure for: rtwdemo_roll
文件 rtwdemo_roll.h 定義了幾種表示內部數據的結構體類型。例如,模塊輸入和輸出結構體為模型中的每個內部信號定義一個字段。每個字段名稱都派生自生成該信號的模塊的名稱,或者派生自該信號的名稱(如果您指定了信號名稱)。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,...
'/* Block signals (default storage) */','} B_rtwdemo_roll_T;',1,1)
/* Block signals (default storage) */
typedef struct {
real32_T phiCmd; /* '/ModeSwitch' */
real32_T Abs; /* '/Abs' */
real32_T FixPtUnitDelay1; /* '/FixPt Unit Delay1' */
real32_T Xnew; /* '/Enable' */
real32_T TKSwitch; /* '/TKSwitch' */
real32_T RefSwitch; /* '/RefSwitch' */
real32_T Integrator; /* '/Integrator' */
real32_T DispLimit; /* '/DispLimit' */
real32_T Sum; /* '/Sum' */
real32_T DispGain; /* '/DispGain' */
real32_T RateLimit; /* '/RateLimit' */
real32_T Sum1; /* '/Sum1' */
real32_T RateGain; /* '/RateGain' */
real32_T Sum2; /* '/Sum2' */
real32_T CmdLimit; /* '/CmdLimit' */
real32_T IntGain; /* '/IntGain' */
real32_T hdgError; /* '/Sum' */
real32_T DispGain_a; /* '/DispGain' */
real32_T Product; /* '/Product' */
boolean_T NotEngaged; /* '/NotEngaged' */
boolean_T TKThreshold; /* '/TKThreshold' */
boolean_T RefThreshold2; /* '/RefThreshold2' */
boolean_T RefThreshold1; /* '/RefThreshold1' */
boolean_T Or; /* '/Or' */
boolean_T NotEngaged_e; /* '/NotEngaged' */
} B_rtwdemo_roll_T;
該文件定義一種 DWork 結構體類型,用于表示模塊狀態,例如 Discrete-Time Integrator 模塊的狀態。
rtwdemodbtype(file,...
'/* Block states (default storage) for system','} DW_rtwdemo_roll_T;',1,1)
/* Block states (default storage) for system '' */
typedef struct {
real32_T FixPtUnitDelay1_DSTATE; /* '/FixPt Unit Delay1' */
real32_T Integrator_DSTATE; /* '/Integrator' */
int8_T Integrator_PrevResetState; /* '/Integrator' */
} DW_rtwdemo_roll_T;
該文件定義一種表示參數數據的結構體類型。模型中的每個可調模塊參數(例如 Gain 模塊的 Gain 參數)顯示為此結構體的一個字段。如果模塊參數從 MATLAB 變量或 Simulink.Parameter 對象獲取其參數值,則該變量或對象顯示為字段,而不是模塊參數。
該文件還定義一種結構體類型,即實時模型數據結構體,其單個字段表示一種運行時指示,用于指示生成的代碼在執行期間是否遇到錯誤。
rtwdemodbtype(file,'/* Real-time Model Data Structure */',...
'/* Block parameters (default storage) */',1,0)
/* Real-time Model Data Structure */
struct tag_RTM_rtwdemo_roll_T {
const char_T *errorStatus;
};
對于表示實時模型數據結構體的結構體類型,文件 rtwdemo_roll_types.h 會創建一個別名,生成的代碼稍后將使用該別名為結構體分配內存。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll_types.h');
rtwdemodbtype(file,'/* Forward declaration for rtModel */',...
'RT_MODEL_rtwdemo_roll_T;',1,1)
/* Forward declaration for rtModel */
typedef struct tag_RTM_rtwdemo_roll_T RT_MODEL_rtwdemo_roll_T;
rtwdemo_roll.c 使用這些結構體類型來定義用于為生成的算法存儲內部數據的全局結構體變量(為其分配內存)。該文件還定義表示實時模型數據結構體的變量和指向該結構體的指針。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
'= &rtwdemo_roll_M_;',1,1)
/* Block signals (default storage) */
B_rtwdemo_roll_T rtwdemo_roll_B;
/* Block states (default storage) */
DW_rtwdemo_roll_T rtwdemo_roll_DW;
/* External inputs (root inport signals with default storage) */
ExtU_rtwdemo_roll_T rtwdemo_roll_U;
/* External outputs (root outports fed by signals with default storage) */
ExtY_rtwdemo_roll_T rtwdemo_roll_Y;
/* Real-time model */
RT_MODEL_rtwdemo_roll_T rtwdemo_roll_M_;
RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M = &rtwdemo_roll_M_;
模型 step 函數(表示主模型算法)使用 void void 接口(不帶參數)。
rtwdemodbtype(file,...
'/* Model step function */','void rtwdemo_roll_step(void)',1,1)
/* Model step function */
void rtwdemo_roll_step(void)
在函數定義中,算法通過直接訪問全局變量來執行計算并將中間結果存儲在信號和狀態結構體中。該算法還從對應的全局變量中讀取參數數據。例如,在 BasicRollMode 子系統中,為 Integrator 模塊生成的代碼在結構體中讀取和寫入信號、狀態和參數數據。
rtwdemodbtype(file,'/* DiscreteIntegrator: ''/Integrator'' *',...
'/* End of DiscreteIntegrator: ''/Integrator'' */',1,1)
/* DiscreteIntegrator: '/Integrator' */
if (rtwdemo_roll_B.NotEngaged_e || (rtwdemo_roll_DW.Integrator_PrevResetState
!= 0)) {
rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;
}
if (rtwdemo_roll_DW.Integrator_DSTATE >= rtwdemo_roll_P.intLim) {
rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.intLim;
} else {
if (rtwdemo_roll_DW.Integrator_DSTATE <= rtwdemo_roll_P.Integrator_LowerSat)
{
rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_LowerSat;
}
}
rtwdemo_roll_B.Integrator = rtwdemo_roll_DW.Integrator_DSTATE;
由于存在 void void 接口和直接數據訪問,該函數不可重入。如果在一個應用程序中多次調用該函數,則每次調用都會將數據寫入全局結構體變量,后續調用可以讀取該數據,從而導致各次調用之間出現意外的干擾。
模型初始化函數 rtwdemo_roll_initialize 將所有內部數據初始化為零。該函數還通過調用專用宏函數對錯誤狀態進行初始化。初始化函數直接訪問全局變量,這意味著該函數不可重入。
rtwdemodbtype(file,'/* Model initialize function */',...
'sizeof(DW_rtwdemo_roll_T));',1,1)
/* Model initialize function */
void rtwdemo_roll_initialize(void)
{
/* Registration code */
/* initialize error status */
rtmSetErrorStatus(rtwdemo_roll_M, (NULL));
/* block I/O */
(void) memset(((void *) &rtwdemo_roll_B), 0,
sizeof(B_rtwdemo_roll_T));
/* states (dwork) */
(void) memset((void *)&rtwdemo_roll_DW, 0,
sizeof(DW_rtwdemo_roll_T));
然后,該函數將 DWork 結構體中的模塊狀態初始化為模型中的模塊參數指定的初始值。模型的三個狀態中的兩個具有可調初始值,因此代碼通過從參數結構體中讀取數據來初始化它們。
rtwdemodbtype(file,...
'/* SystemInitialize for Atomic SubSystem: ''/RollAngleReference'' */',...
'/* Model terminate function */',1,0)
/* SystemInitialize for Atomic SubSystem: '/RollAngleReference' */
/* InitializeConditions for UnitDelay: '/FixPt Unit Delay1' */
rtwdemo_roll_DW.FixPtUnitDelay1_DSTATE = rtwdemo_roll_P.LatchPhi_vinit;
/* End of SystemInitialize for SubSystem: '/RollAngleReference' */
/* SystemInitialize for Atomic SubSystem: '/BasicRollMode' */
/* InitializeConditions for DiscreteIntegrator: '/Integrator' */
rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;
rtwdemo_roll_DW.Integrator_PrevResetState = 0;
/* End of SystemInitialize for SubSystem: '/BasicRollMode' */
}
生成可重用的代碼
您可以將生成的代碼配置為可重入代碼,這意味著您可以在一個應用程序中多次調用入口函數。使用此配置時,入口函數并不直接訪問全局變量,而是通過形參(指針參數)接受內部數據。通過使用這些指針參數,每次調用都可以在一組單獨的全局變量中維護內部數據,從而防止各次調用之間出現意外的交互。
在模型中,將 Configuration Parameters > Code Generation > Interface > Code interface packaging 設置為 Reusable function。
set_param('rtwdemo_roll','CodeInterfacePackaging','Reusable function')
從模型中生成代碼。
rtwbuild('rtwdemo_roll')
### Starting build procedure for: rtwdemo_roll
### Successful completion of build procedure for: rtwdemo_roll
現在,在 rtwdemo_roll.h 中,實時模型數據結構體包含指向錯誤指示的指針、內部數據以及 ExtU 和 ExtY 子結構體形式的主輸入和輸出數據(其字段表示模型根級別的 Inport 和 Outport 模塊)。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,'/* Real-time Model Data Structure */',...
'/* External data declarations for dependent source files */',1,0)
/* Real-time Model Data Structure */
struct tag_RTM_rtwdemo_roll_T {
const char_T *errorStatus;
B_rtwdemo_roll_T *blockIO;
ExtU_rtwdemo_roll_T *inputs;
ExtY_rtwdemo_roll_T *outputs;
DW_rtwdemo_roll_T *dwork;
};
/* Block parameters (default storage) */
extern P_rtwdemo_roll_T rtwdemo_roll_P;
要在一個應用程序中多次調用生成的代碼,您的代碼必須在每次調用時為實時模型數據結構體分配內存。文件 rtwdemo_roll.c 定義一個專用函數,它為新實時模型數據結構體分配內存并返回指向該結構體的指針。該函數還為模型數據結構體中的字段指向的子結構體(例如 DWork 結構體)分配內存。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Model data allocation function */',...
'RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)',1,1)
/* Model data allocation function */
RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)
模型 step 函數接受表示實時模型數據結構體的參數。
rtwdemodbtype(file,'/* Model step function */','void rtwdemo_roll_step',1,1)
/* Model step function */
void rtwdemo_roll_step(RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M)
在函數定義中,算法首先將每個指針從實時模型數據結構體中提取到局部變量中。
rtwdemodbtype(file,'*rtwdemo_roll_B =','rtwdemo_roll_M->outputs;',1,1)
B_rtwdemo_roll_T *rtwdemo_roll_B = ((B_rtwdemo_roll_T *)
rtwdemo_roll_M->blockIO);
DW_rtwdemo_roll_T *rtwdemo_roll_DW = ((DW_rtwdemo_roll_T *)
rtwdemo_roll_M->dwork);
ExtU_rtwdemo_roll_T *rtwdemo_roll_U = (ExtU_rtwdemo_roll_T *)
rtwdemo_roll_M->inputs;
ExtY_rtwdemo_roll_T *rtwdemo_roll_Y = (ExtY_rtwdemo_roll_T *)
rtwdemo_roll_M->outputs;
然后,為了訪問存儲在全局內存中的內部數據,該算法與這些局部變量交互。
rtwdemodbtype(file,'/* DiscreteIntegrator: ''/Integrator'' */',...
'/* End of DiscreteIntegrator: ''/Integrator'' */',1,1)
/* DiscreteIntegrator: '/Integrator' */
if (rtwdemo_roll_B->NotEngaged_e ||
(rtwdemo_roll_DW->Integrator_PrevResetState != 0)) {
rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;
}
if (rtwdemo_roll_DW->Integrator_DSTATE >= rtwdemo_roll_P.intLim) {
rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P.intLim;
} else {
if (rtwdemo_roll_DW->Integrator_DSTATE <= rtwdemo_roll_P.Integrator_LowerSat)
{
rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P.Integrator_LowerSat;
}
}
rtwdemo_roll_B->Integrator = rtwdemo_roll_DW->Integrator_DSTATE;
同樣,模型初始化函數接受實時模型數據結構體作為參數。
rtwdemodbtype(file,...
'/* Model initialize function */','void rtwdemo_roll_initialize',1,1)
/* Model initialize function */
void rtwdemo_roll_initialize(RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M)
由于您對入口函數的每次調用都與一個單獨的實時模型數據結構體交互,因此可以避免各次調用之間發生意外交互。
使用代碼生成優化消除內部數據
為了獲得消耗更少內存的更高效代碼,請選擇優化,例如您在前面清除了的 Default parameter behavior。
set_param('rtwdemo_roll','DefaultParameterBehavior','Inlined',...
'OptimizeBlockIOStorage','on',...
'LocalBlockOutputs','on')
在此示例中,為了獲得更簡單的代碼,請將 Code interface packaging 設置為 Nonreusable function。
set_param('rtwdemo_roll','CodeInterfacePackaging','Nonreusable function')
從模型中生成代碼。
rtwbuild('rtwdemo_roll')
### Starting build procedure for: rtwdemo_roll
### Successful completion of build procedure for: rtwdemo_roll
現在,rtwdemo_roll.h 沒有定義用于模塊輸入和輸出的結構體。對于模型中的所有內部信號,優化要么已消除了存儲,要么創建了局部函數變量而不是全局結構體字段。
優化未能消除三種模塊狀態的存儲,因此文件繼續定義 DWork 結構體類型。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,...
'/* Block states (default storage) for system','} DW_rtwdemo_roll_T;',1,1)
/* Block states (default storage) for system '' */
typedef struct {
real32_T FixPtUnitDelay1_DSTATE; /* '/FixPt Unit Delay1' */
real32_T Integrator_DSTATE; /* '/Integrator' */
int8_T Integrator_PrevResetState; /* '/Integrator' */
} DW_rtwdemo_roll_T;
現在,為 Discrete-Time Integrator 模塊生成的代碼僅在 DWork 結構體中存儲狀態和輸出數據。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Update for DiscreteIntegrator: ''/Integrator''',...
'/* End of Update for DiscreteIntegrator: ''/Integrator'' */',1,1)
/* Update for DiscreteIntegrator: '/Integrator' incorporates:
* Gain: '/IntGain'
*/
rtwdemo_roll_DW.Integrator_DSTATE += 0.5F * rtb_TKSwitch * 0.025F;
if (rtwdemo_roll_DW.Integrator_DSTATE >= 5.0F) {
rtwdemo_roll_DW.Integrator_DSTATE = 5.0F;
} else {
if (rtwdemo_roll_DW.Integrator_DSTATE <= -5.0F) {
rtwdemo_roll_DW.Integrator_DSTATE = -5.0F;
}
}
rtwdemo_roll_DW.Integrator_PrevResetState = (int8_T)rtb_NotEngaged_f;
優化還消除了模型中模塊參數的存儲。例如,在 Discrete-Time Integrator 模塊中,Upper saturation limit 和 Lower saturation limit 參數設置為 intLim 和 -intLim。intLim 是 Simulink.Parameter 對象,用于存儲值 5。在為 Discrete-Time Integrator 生成的代碼中,這些模塊參數和 intLim 顯示為內聯字面數字 5.0F 和 -5.0F。
如果模型包含代碼生成器不能直接內聯的參數(例如數組參數),則代碼會定義表示該數據的結構體類型。此常量參數結構體使用 const 存儲類型限定符,因此某些編譯工具鏈可以進一步優化程序集代碼。
總結
以上是生活随笔為你收集整理的matlab 生成信号文件,生成的代码如何存储内部信号、状态和参数数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python读取文件内容操作_Pytho
- 下一篇: AndroidJava List与equ