CANoe:第5个仿真工程:仿真+测试
目錄
工程背景
工程目的
報文發(fā)送情況
工程實現(xiàn)
工程步驟概述
1 測試方法分析
1-1 檢測報文周期
1-2 檢測報文長度DLC
1-3?功能測試
1-4?檢測未定義報文
2 添加Test Module
2-1創(chuàng)建測試環(huán)境
?2-2 插入CAPL Test Module
3?CAPL編寫測試用例
?3-1?測試模塊入口函數(shù)MainTest
3-2 CAPL測試用例——檢測報文周期
3-3 CAPL測試用例——檢測報文長度DLC
3-4 CAPL測試用例——檢測未定義報文undefined msg
3-5 CAPL測試用例——功能測試
4 工程運行測試
?5 故障注入
5-1 系統(tǒng)變量控制報文發(fā)送
5-2? IG節(jié)點發(fā)送自定義報文
?6 測試報告
工程背景
本工程主要目的是: 基于第3個仿真工程, 熟悉CANoe的報文測試功能。
工程目的
本工程將圍繞CAN總線中的報文,在Test Module中實現(xiàn)測試功能。主要包括:
報文發(fā)送情況
第3個仿真工程報文發(fā)送與接收情況如下:
報文的相關(guān)屬性整理如下表:
報文中的信號屬性如下表:
?
工程實現(xiàn)
工程步驟概述
本章實例基于第12章的仿真工程,為了便于區(qū)別,需要將原工程的文件夾復(fù)制并 名為Vehicle_System_Simulation_Test, 工程名稱也另存為Vehicle_System_CAN_Test.cfg, 在該工程文件夾下創(chuàng)建一個名為Testmodul的文件夾,用于存放相關(guān)的測試代碼。
接下來,將在此基礎(chǔ)上添加測試模塊及故障注入面板等。
工程包括以下幾個關(guān)鍵步驟:
1 測試方法分析
本工程的目的是分別測試不同報文的發(fā)送周期、報文長度DLC;功能測試(檢測信號值是否在期望的數(shù)值范圍內(nèi) );未定義報文。
1-1 檢測報文周期
檢測報文周期的方法是劃定某一段特定的時間,選取該時間段中第一條待測報文作為起始時間戳,觀察此待測報文后續(xù)重復(fù)的時間間隔。
TSL函數(shù)——檢測函數(shù)
檢測函數(shù)1:
ChkStart_MsgAbsCycleTimeViolation ( Message aObservedMessage,duration aMinCycleTime, duration aMaxCycleTime)
函數(shù)功能:觀察總線周期性報文aObservedMessage的每次出現(xiàn),如果該報文的間隔不符合規(guī)范要求,則會觸發(fā)一個代表異常出現(xiàn)的特殊事件。
返回值:>0,返回一個IDaCheckedId,即觀察待測報文的事件;=0報錯。
TSL函數(shù)——狀態(tài)報告函數(shù)
狀態(tài)報告函數(shù)1:long ChKQuery_NumEvents(dword aCheckId)?
函數(shù)功能:查詢該時間段內(nèi)異常出現(xiàn)的特殊事件的個數(shù)
狀態(tài)報告函數(shù)2:double ChkQuery_StatProbeIntervalAvg(dword aCheckId)
返回該時間段內(nèi),該報文的平均周期間隔時間
狀態(tài)報告函數(shù)3: double ChkQuery_StatProbeIntervalMin(dword aCheckId)
返回該時間段內(nèi),該報文的最小周期間隔時間
狀態(tài)報告函數(shù)4: double ChkQuery_StatProbeIntervalMax(dword aCheckId)
返回該時間段內(nèi),該報文的最大周期間隔時間
TSL函數(shù)——檢測控制函數(shù)
檢測控制函數(shù)1: long ChkControl_Destroy(Check aCheckId)
用于測試結(jié)束時,銷毀該事件對象aCheckId,釋放資源。返回0操作成功,<0報錯。
1-2 檢測報文長度DLC
函數(shù):
-
狀態(tài)報告函數(shù) ChkQuery_NumEvents
-
檢測控制函數(shù) ChkControl_Destroy
-
檢測函數(shù):dword ChkStart_InconsistentDLC(Message aMessage,char [] aCallback)
-
檢測發(fā)送到總線上指定報文長度是否與DBC數(shù)據(jù)庫中的定義一致
-
aMessage待測報文;char [] aCallback回調(diào)函數(shù)名,可選參數(shù)
-
返回值:>0:返回一個事件對象aCheckId;=0報錯
-
1-3?功能測試
功能測試用過CAPL程序邏輯來設(shè)置某信號的數(shù)值,然后使用ChkStart_MsgSignalValueInvalid函數(shù)來檢測信號值是否在期望的數(shù)值范圍內(nèi)。
dword ChkStart_MsgSignalValueInvalid (Signal aObservedSignal,double aMinValue, double aMaxValue, Callback aCallback)
函數(shù)參數(shù):待測信號,必須是定在DBC中的信號,最小信號值,最大信號值,回調(diào)CAPL函數(shù)名,可選。
返回值:返回一個事件對象aCheckId,即檢測未定義報文的事件
1-4?檢測未定義報文
檢測函數(shù):dword ChkStart_UndefinedMessageReceived (char [] CaplCallback)
作用:觀察當前總線上是否有未定義的報文
返回值:>0:返回一個事件對象aCheckId,即待觀測報文的事件;=0報錯。
狀態(tài)報告函數(shù):long ChkQuery_EventMessageId (dword aCheckId)
作用:返回觸發(fā)該事件的報文的MessageId
返回值:>0返回觸發(fā)該事件的報文ID;<0報錯。
2 添加Test Module
2-1創(chuàng)建測試環(huán)境
創(chuàng)建測試環(huán)境,命名為NetworkTester。
?2-2 插入CAPL Test Module
插入CAPL Test Module,并配置此模塊Configuration對話框
?配置Module的Name為:Network Tester,在TestModule文件夾下創(chuàng)建CAPL文件NetworkTester.can
3?CAPL編寫測試用例
?選中TestModule,右鍵選中Edit,可以編輯NetworkTester.can 。
?3-1?測試模塊入口函數(shù)MainTest
CAPL測試模塊中can文件要求:-必須包含MainTest函數(shù),所有的測試用例均從此接口進入
3-2 CAPL測試用例——檢測報文周期
分別測試EngineData(50),VehicleData(50),Gear_Info(50),Ignition_Info(50) ,Light_Info(500)的報文周期。
以EngineData為例,CAPL程序邏輯如下:
其他報文只需在3測試用例部分,改為相應(yīng)的報文名稱即可。1聲明檢測事件,4用例檢測結(jié)果,5銷毀檢測事件都是通用功能。
具體代碼示例如下:
variables {//TC1dword gCycCheckId;//聲明檢測事件的IDint gUndefinedMsgCheckResult;//聲明未定義報文的檢測結(jié)果const long kMIN_CYCLE_TIME = 40;//一般最小周期時間常量const long kMAX_CYCLE_TIME = 60;//一般最大周期時間常量const long Light_MIN_CYCLE_TIME = 490;//定義報文Light_Info最小周期時間常量const long Light_MAX_CYCLE_TIME = 510;//定義報文Light_Info最大周期時間常量const long kTIMEOUT = 4000;//定義測試等待時間常量//自定義報文——使用IG模塊}//周期時間檢測結(jié)果函數(shù) CheckMsgCyc(float aCycMinCycleTime, float aCycMaxCycleTime) {long lQueryResultProbeAvg;//聲明平均時間long lQueryResultProbeMin;//聲明最小測量時間long lQueryResultProbeMax;//聲明最大測量時間char lbuffer[100];testAddCondition(gCycCheckId);//在該函數(shù)中添加事件testWaitForTimeout(kTIMEOUT);//等待測試時間結(jié)束//統(tǒng)計平均時間lQueryResultProbeAvg = ChkQuery_StatProbeIntervalAvg(gCycCheckId);//統(tǒng)計min時間lQueryResultProbeMin = ChkQuery_StatProbeIntervalMin(gCycCheckId);//統(tǒng)計max時間lQueryResultProbeMax = ChkQuery_StatProbeIntervalMax(gCycCheckId); if(ChkQuery_NumEvents(gCycCheckId)>0){//統(tǒng)計異常次數(shù)//打印報告snprintf(lbuffer,elCount(lbuffer),"Valid values %.0fms - %.0fms",aCycMinCycleTime,aCycMaxCycleTime);testStepFail("",lbuffer);snprintf(lbuffer,elCount(lbuffer),"Average cycle time: %dms",lQueryResultProbeAvg);testStepFail("",lbuffer);snprintf(lbuffer,elCount(lbuffer),"Min cycle time: %dms",lQueryResultProbeMin);testStepFail("",lbuffer);snprintf(lbuffer,elCount(lbuffer),"Average cycle time: %dms",lQueryResultProbeMax);testStepFail("",lbuffer);}else{snprintf(lbuffer,elCount(lbuffer),"Valid values %.0fms - %.0fms",aCycMinCycleTime,aCycMaxCycleTime);testStepPass("",lbuffer);snprintf(lbuffer,elCount(lbuffer),"Average cycle time: %dms",lQueryResultProbeAvg);testStepPass("",lbuffer);snprintf(lbuffer,elCount(lbuffer),"Min cycle time: %dms",lQueryResultProbeMin);testStepPass("",lbuffer);snprintf(lbuffer,elCount(lbuffer),"Average cycle time: %dms",lQueryResultProbeMax);testStepPass("",lbuffer);}ChkControl_Destroy(gCycCheckId);//銷毀事件}//TC1:Check Cycle time of msg EngineData testcase CheckMsgEngineData() {float lCycMinCycleTime;//聲明最小周期時間float lCycMaxCycleTime;//聲明最大周期時間lCycMinCycleTime = kMIN_CYCLE_TIME;//賦值lCycMaxCycleTime = kMAX_CYCLE_TIME;//測試報告提示信息testCaseTitle("TC-1","TC-1:Check cycle time of msg EngineData");//開始觀察待測報文gCycCheckId = ChkStart_MsgAbsCycleTimeViolation(EngineData,lCycMinCycleTime,lCycMaxCycleTime);CheckMsgCyc(lCycMinCycleTime,lCycMaxCycleTime);//周期時間檢測結(jié)果函數(shù)testRemoveCondition(gCycCheckId);//移除測試條件 } //TC-2:Check Cycle time of msg VehicleData testcase CheckMsgVehicleData() {float lCycMinCycleTime;float lCycMaxCycleTime;lCycMinCycleTime = kMIN_CYCLE_TIME;lCycMaxCycleTime = kMAX_CYCLE_TIME;testCaseTitle("TC-2","TC-2:Check cycle time of msg VehicleData");gCycCheckId = ChkStart_MsgAbsCycleTimeViolation(VehicleData,lCycMinCycleTime,lCycMaxCycleTime);CheckMsgCyc(lCycMinCycleTime,lCycMaxCycleTime);testRemoveCondition(gCycCheckId); } //TC-3:Check Cycle time of msg Gear_Info testcase CheckMsgGear_Info() {float lCycMinCycleTime;float lCycMaxCycleTime;lCycMinCycleTime = kMIN_CYCLE_TIME;lCycMaxCycleTime = kMAX_CYCLE_TIME;testCaseTitle("TC-3","TC-3:Check cycle time of msg Gear_Info");gCycCheckId = ChkStart_MsgAbsCycleTimeViolation(Gear_Info,lCycMinCycleTime,lCycMaxCycleTime);CheckMsgCyc(lCycMinCycleTime,lCycMaxCycleTime);testRemoveCondition(gCycCheckId); } //TC-4:Check Cycle time of msg Ignition_Info testcase CheckMsgIgnition_Info() {float lCycMinCycleTime;float lCycMaxCycleTime;lCycMinCycleTime = kMIN_CYCLE_TIME;lCycMaxCycleTime = kMAX_CYCLE_TIME;testCaseTitle("TC-4","TC-4:Check cycle time of msg Ignition_Info");gCycCheckId = ChkStart_MsgAbsCycleTimeViolation(Ignition_Info,lCycMinCycleTime,lCycMaxCycleTime);CheckMsgCyc(lCycMinCycleTime,lCycMaxCycleTime);testRemoveCondition(gCycCheckId); } //TC-5:Check Cycle time of msg Light_Inf testcase CheckMsgLight_Info() {float lCycMinCycleTime;float lCycMaxCycleTime;lCycMinCycleTime = kMIN_CYCLE_TIME;lCycMaxCycleTime = kMAX_CYCLE_TIME;testCaseTitle("TC-5","TC-5:Check cycle time of msg Light_Info");gCycCheckId = ChkStart_MsgAbsCycleTimeViolation(Light_Info,lCycMinCycleTime,lCycMaxCycleTime);CheckMsgCyc(lCycMinCycleTime,lCycMaxCycleTime);testRemoveCondition(gCycCheckId); }3-3 CAPL測試用例——檢測報文長度DLC
//TC6:DLC 報文長度測試 testcase CheckDLCLock_Info() {dword checkId;//測試報告提示信息testCaseTitle("TC-6","TC-6:Check msg DLC of Lock_Info");//管事觀測報文Lock_Info的DLCcheckId = ChkStart_InconsistentDlc(Lock_Info);testAddCondition(checkId);//等待測試時間結(jié)束testWaitForTimeout(kTIMEOUT);testRemoveCondition(checkId); }3-4 CAPL測試用例——檢測未定義報文undefined msg
//TC-7:檢測未定義信號 testcase CheckUndefinedMessage() {long lEventUndefineMessageId;//聲明未定義報文Idchar lbuffer[100];gUndefinedMsgCheckResult = 0;//?初始化未定義報文數(shù)量為0testCaseTitle("TC-7","TC-7:Check CAN channel for undefined message");//開始觀測當前總線gCycCheckId = ChkStart_UndefinedMessageReceived("UndefinedMsgCallback");//延時,即測量該時間段testWaitForTimeout(kTIMEOUT);switch(gUndefinedMsgCheckResult){case 1:write("undefined message detected!");//獲取未定義報文IDlEventUndefineMessageId = ChkQuery_EventMessageId(gCycCheckId);snprintf(lbuffer,elCount(lbuffer),"Undefined message detected: Id 0x%x",lEventUndefineMessageId);testStepFail("",lbuffer);break;default:write("Iamdefault");testStepPass("","No undefined message detected!");break; }ChkControl_Destroy(gCycCheckId);//銷毀事件 }UndefinedMsgCallback(dword aCheckId) {//回調(diào)函數(shù),檢測到未定義報文時調(diào)用write("Test: undefined message finded");ChkQuery_EventStatusToWrite(aCheckId);gUndefinedMsgCheckResult=1;//將未定義報文個數(shù)置為1 }3-5 CAPL測試用例——功能測試
testcase CheckEngine_Speed() {dword checkId;testCaseTitle("TC-8","TC-8:Check Engine Speed Value");@Vehicle_Key::Unlock_Car = 1;@Vehicle_Key::Car_Driver = 0;@Vehicle_Key::Key_State = 2;@Vehicle_Control::Eng_Speed = 2000;//開始觀測,信號值是否在范圍內(nèi)checkId = ChkStart_MsgSignalValueInvalid(EngineData::EngSpeed,1900,2100);testWaitForTimeout(kTIMEOUT);if(ChkQuery_EventSignalValue(checkId)){testStepPass("","Correct Engine Speed Value");}else{testStepFail("","Incorrect Engine Speed Value");} }4 工程運行測試
運行工程后,運行測試。
測試用例運行結(jié)果如圖所示,Light_Info的報文周期檢測報錯。
——查看CANdb,發(fā)現(xiàn)只有報文Light_Info的報文周期為500,代碼中使用的檢測范圍為40-60,將周期范圍更改為Light_MIN_CYCLE_TIME和Light_MAX_CYCLE_TIME,如下示例:
//TC-5:Check Cycle time of msg Light_Info testcase CheckMsgLight_Info() {float lCycMinCycleTime;float lCycMaxCycleTime;//lCycMinCycleTime = kMIN_CYCLE_TIME;//kMIN_CYCLE_TIME=40==>Light_MIN_CYCLE_TIME=490//lCycMaxCycleTime = kMAX_CYCLE_TIME;//kMAX_CYCLE_TIME=60==>Light_MAX_CYCLE_TIME=510lCycMinCycleTime = Light_MIN_CYCLE_TIME;lCycMaxCycleTime = Light_MAX_CYCLE_TIME;testCaseTitle("TC-5","TC-5:Check cycle time of msg Light_Info");gCycCheckId = ChkStart_MsgAbsCycleTimeViolation(Light_Info,lCycMinCycleTime,lCycMaxCycleTime);CheckMsgCyc(lCycMinCycleTime,lCycMaxCycleTime);testRemoveCondition(gCycCheckId); }再次運行測試用例,全部通過。
?5 故障注入
為了驗證測試用例的正確性,可以使用多種故障注入方法實現(xiàn)故障注入,常見的有:使用故障注入函數(shù),采用網(wǎng)絡(luò)節(jié)點CAPL編程,以及使用IG節(jié)點。
書中制作了一個面板: Msg_Switch和Custom_Msg,分別控制報文的發(fā)送和關(guān)閉,以及發(fā)送自定義報文。
?我自己嘗試使用Panel模塊實現(xiàn)這個面板:創(chuàng)建系統(tǒng)變量,將面板復(fù)選框關(guān)聯(lián)系統(tǒng)變量,再在CAPL編程中讀取系統(tǒng)變量,根據(jù)變量值控制對應(yīng)的報文函數(shù)。
但最后,使用Panel只實現(xiàn)了Msg_Switch部分。Custom_Msg沒有找到對應(yīng)的未定義報文創(chuàng)建方法,有實現(xiàn)的小伙伴歡迎分享。最后使用IG節(jié)點實現(xiàn)了未定義報文的發(fā)送。
5-1 系統(tǒng)變量控制報文發(fā)送
創(chuàng)建系統(tǒng)變量,將面板復(fù)選框關(guān)聯(lián)系統(tǒng)變量,再在CAPL編程中讀取系統(tǒng)變量,根據(jù)變量值控制對應(yīng)的報文函數(shù)。
測試用例涉及7個報文,因而創(chuàng)建7個系統(tǒng)變量創(chuàng)建如下:
?以Gateway_EngineData_off為例,系統(tǒng)變量創(chuàng)建過程如下。
先建立一個Value Table共同使用。因為7個系統(tǒng)變量具有相同的數(shù)值解釋:勾選為1代表停止報文發(fā)送,不勾選為0代表報文正常發(fā)送。使用相同的ValueTable可以統(tǒng)一管理。
?Panel創(chuàng)建過程如下:
先添加一個Panel面板,命名為NetworkTest.
添加復(fù)選框組件,修改名稱并,關(guān)聯(lián)對應(yīng)的系統(tǒng)變量,下圖示例為EngineData,其余報文控制根據(jù)名稱一一對應(yīng)即可。
?Panel創(chuàng)建完畢后,在NetworkTest.can中添加變量監(jiān)聽事件,控制相應(yīng)的報文發(fā)送。
以EngineData為例,CAPL編程如下:
on sysvar_update TestSysVar::Gateway_EngineData_off {if (@this==1){testDisableMsg(EngineData);write("Test: disable EngineData");//testDisableMsg(Cluster_Info);// ILDisableMsg("Cluster_Info");}else{testEnableMsg(EngineData);write("Test: enable EngineData");} }控制報文發(fā)送和終止的函數(shù)不止有testDisableMsg和testEnableMsg,其它函數(shù)可以參考此文(完善后放鏈接)。
5-2? IG節(jié)點發(fā)送自定義報文
IG節(jié)點可分為?CAN IG和IG,區(qū)別是CANIG只支持CAN報文,而IG可支持CAN、LIN、MOST等其他報文。此外還有IG和PDU IG的區(qū)別,PDU IG可以支持任意網(wǎng)絡(luò)協(xié)議,包括CAN以及Ethernet 、FlexRay。
?5-2-1 創(chuàng)建IG節(jié)點
在Simulation Setup總線上創(chuàng)建CAN IG 模塊,CAN IG模塊允許用戶發(fā)送自定義的CAN報文。
5-2-2 添加自定義報文,并配置
?如上圖添加了3個自定義報文Msg_01,Msg_02,Msg_03,并按下圖定義相關(guān)屬性
?5-2-3 運行
保存后,啟動工程,啟動測試用例,發(fā)送自定義報文。
測試結(jié)果顯示檢測到了未定義報文。
?6 測試報告
測試報告有2種格式:①CANoe TestReport Viewer(推薦)②XML/HTML格式(以前的)
可如下圖所示,修改為自己所需的格式:
?測試報告的打開位置如下
①CANoe TestReport Viewer(推薦)
?②XML/HTML格式(以前的)
?
END?
總結(jié)
以上是生活随笔為你收集整理的CANoe:第5个仿真工程:仿真+测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android动态壁纸--美女报时
- 下一篇: 我没去BAT,用了8年时间,从乙方变成了