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