文章目錄
- 前言
- Autosar Nvm接口
- 設計模型及接口
- 生成代碼及arxml
- RTE接口mapping
- RTE代碼分析
- 總結
前言
之前介紹過Simulink開發Dem故障觸發邏輯,本文接著介紹另外一個常用的功能-Nvm存儲的實現。
Autosar Nvm接口
Autosar Nvm中一般在上電初始化的時調用Nvm_ReadAll獲取Nvm block的數據到Ram中。對于block來說,可以通過Nvm_ReadBlock進行讀取,通過Nvm_WriteBlock進行寫入。Autosar Dem標準接口為NvMService,使用Simulink中自帶的demo-autosar_bsw_sensor中的定義,如下所示:
需要注意的是:生成的package位置為/AUTOSAR/Services/Dem(暫時沒找到怎么修改),而在使用時,導入對應Autosar工具(例如Etas)時可能會找不到對應的定義。此處我們后面是手動更改arxml中的package路徑
設計模型及接口
配置Nvm的ClientPort,如下所示
Nvm需要使用到Simulink自帶的Data Store Memory模塊,如下所示
在初始化函數中進行Nvm讀取
配置Nvm的Port及讀取的函數
做了一個簡單的存儲邏輯:當輸入值小于存儲的值時,觸發Nvm的存儲
寫入需要使用Data Store Write,然后使用Data Store Read調用WriteBlock進行寫入,如下所示
配置Nvm的Port及寫入的函數
Nvm的Functions Callers在刷新后會自動生成并mapping
生成代碼及arxml
生成的代碼中調用了RTE函數Rte_Call_S1LowSetPoint_ReadBlock用來讀取Nvm,調用RTE函數Rte_Call_S1LowSetPoint_WriteBlock用來寫入Nvm,示例如下:
/* Model step function */
void Runnable_Step(void)
{uint16 rtb_RelationalOperator_tmp;boolean rtb_RelationalOperator;/* Outport: '<Root>/Percent' incorporates:* DataTypeConversion: '<Root>/Data Type Conversion'* Inport: '<Root>/RawADC'* Lookup_n-D: '<Root>/TPS Lookup'*/Rte_IWrite_Runnable_Step_Percent_Percent(rtCP_TPSLookup_tableData[plook_u32f_linckan(Rte_IRead_Runnable_Step_RawADC_RawADC(), rtCP_TPSLookup_bp01Data, 10U)]);/* Outputs for Triggered SubSystem: '<Root>/Enabled Subsystem' incorporates:* TriggerPort: '<S1>/Trigger'*//* RelationalOperator: '<Root>/Relational Operator' incorporates:* DataStoreWrite: '<S1>/Data Store Write'* Inport: '<Root>/RawADC'*/rtb_RelationalOperator_tmp = Rte_IRead_Runnable_Step_RawADC_RawADC();/* End of Outputs for SubSystem: '<Root>/Enabled Subsystem' *//* RelationalOperator: '<Root>/Relational Operator' incorporates:* DataStoreRead: '<Root>/Data Store Read'* Inport: '<Root>/RawADC'*/rtb_RelationalOperator = (rtb_RelationalOperator_tmp < rtARID_DEF.LowSetPoint);/* Outputs for Triggered SubSystem: '<Root>/Enabled Subsystem' incorporates:* TriggerPort: '<S1>/Trigger'*/if (rtb_RelationalOperator && (rtARID_DEF.EnabledSubsystem_Trig_ZCE !=POS_ZCSIG)) {/* DataStoreWrite: '<S1>/Data Store Write' */rtARID_DEF.LowSetPoint = rtb_RelationalOperator_tmp;/* FunctionCaller: '<S1>/NvMServiceCaller1' */Rte_Call_S1LowSetPoint_WriteBlock(&rtARID_DEF.LowSetPoint);}rtARID_DEF.EnabledSubsystem_Trig_ZCE = rtb_RelationalOperator;/* End of Outputs for SubSystem: '<Root>/Enabled Subsystem' */
}/* Model initialize function */
void Runnable_Init(void)
{/* Start for DataStoreMemory: '<Root>/Data Store Memory' */rtARID_DEF.LowSetPoint = 50U;/* SystemInitialize for Triggered SubSystem: '<Root>/Enabled Subsystem' */rtARID_DEF.EnabledSubsystem_Trig_ZCE = ZERO_ZCSIG;/* End of SystemInitialize for SubSystem: '<Root>/Enabled Subsystem' *//* Outputs for Atomic SubSystem: '<Root>/Initialize_Function' *//* FunctionCaller: '<S2>/NvMServiceCaller' */Rte_Call_S1LowSetPoint_ReadBlock(&rtARID_DEF.LowSetPoint);/* End of Outputs for SubSystem: '<Root>/Initialize_Function' */
}
對應的arxml中也生成了對應的接口描述
此處對應的package路徑不對,需要替換成ETAS Nvm對應路徑(/AUTOSAR_NvM/PortInterfaces/),替換完后copy到ETAS工具鏈中
RTE接口mapping
如果是新增的SWC,還需要將SWC映射到對應的EcucPartition上,且對應的runnable也要映射到對應的task上,本文不介紹這部分內容,默認上述工作已經完成
注意:初始化的Runnable在SWC中沒有對應的Event,原因是Simulink中未配置,需要配置如下:
此處默認對應的NVM block已經建立好了(Nvm block需要配置NvMRbGenRteServicePort為True)。在對應的Nvm ServiceSwComponent中已經有了對應的Pport
Simulink生成的Arxml中的SWC中已經有了對應的NVM接口(Rport,Client接口)
Runnable中也有了對應調用關系
注意:此處生成的Server Call Point是Async接口,會導致后面ETAS生成RTE時生成Alarm和其他無關的代碼,我們不需要,此處需要手動修改為Sync接口,如下所示:
將SWC接口與NVM接口進行mapping
mapping好后進行ECU Extract,然后生成RTE代碼即可
RTE代碼分析
在生成的SWC RTE頭文件中,有對應的接口調用宏定義
#if defined(RTE_PRV_ALL_API) || defined(RTE_RUNNABLEAPI_Runnable_Init)
/* Inline function call optimization; Rte_Call_S1LowSetPoint_ReadBlock to NvM_ReadBlock */
#define Rte_Call_S1LowSetPoint_ReadBlock( DstPtr ) NvM_ReadBlock(((VAR(NvM_BlockIdType, AUTOMATIC))43), DstPtr)#endif
#if defined(RTE_PRV_ALL_API) || defined(RTE_RUNNABLEAPI_Runnable_Step)
/* Inline function call optimization; Rte_Call_S1LowSetPoint_WriteBlock to NvM_WriteBlock */
#define Rte_Call_S1LowSetPoint_WriteBlock( SrcPtr ) NvM_WriteBlock(((VAR(NvM_BlockIdType, AUTOMATIC))43), SrcPtr)#endif
自動生成的宏中實際也是調用的對應Nvm的函數,只是加上了對應的Nvm id,這樣的話,應用層也不需要關心是具體是哪個Nvm id了
總結
使用Simulink Nvm模塊可以減少一部分Nvm相關的RTE接口,能夠節省一部分存儲交互的工作量。