CAPL針對ECU的診斷,提供了一些基本的函數(shù):
下面結(jié)合TestModule 和 診斷的函數(shù),完成ECU的自動化測試
示例1:通過診斷的10服務(wù),進(jìn)行會話的切換測試
MainTest(){
// 設(shè)置后續(xù)所有診斷通信所關(guān)聯(lián)的ECU
diagSetTarget("DoorFL"); //DoorFL 從右側(cè)復(fù)制
demo1();
}
/*
為什么不使用message直接發(fā)送?
因?yàn)椴捎胢sg,需要自己配置很多的參數(shù)信息,需要ID,而diagnostic則有現(xiàn)成的;
理論上,所有發(fā)送到can總線的報(bào)文,其實(shí)都可以使用msg,只不過這里diagnostic更方便
*/
/*
進(jìn)入擴(kuò)展會話
*/
void demo1(){
// 創(chuàng)建了一個進(jìn)入擴(kuò)展會話的“診斷請求變量”
diagRequest DoorFL.ExtendedDiagnosticSession_Start reqExtendedSession;
// 創(chuàng)建一個變量代表診斷響應(yīng)返回的響應(yīng)碼
long respCode;
//發(fā)送請求
diagSendRequest(reqExtendedSession);
//等待請求發(fā)送完畢
if(testWaitForDiagRequestSent(reqExtendedSession, 1000) == 1)
{
write("進(jìn)入擴(kuò)展會話的請求發(fā)送完畢");
}
else
{
write("進(jìn)入擴(kuò)展會話的請求發(fā)送失敗");
return;
}
//等待接收到診斷的響應(yīng)
if(testWaitForDiagResponse(reqExtendedSession,1000) == 1){
write("進(jìn)入擴(kuò)展會話的響應(yīng)已經(jīng)收到");
}
else
{
write("進(jìn)入擴(kuò)展會話的響應(yīng)未收到");
return;
}
respCode = diagGetLastResponseCode(reqExtendedSession);
if(respCode == -1) // 肯定響應(yīng)
{
write("進(jìn)入擴(kuò)展會話的響應(yīng)為肯定響應(yīng)");
}
else if(respCode == 0) // 未收到響應(yīng)
{
write("進(jìn)入擴(kuò)展會話的響應(yīng)還沒收到");
}
else
{
write("進(jìn)入會展會話的響應(yīng)為否定響應(yīng)炕檩,NRC為:0x%02X", respCode);
}
//把信息寫入報(bào)告中;
testReportWriteDiagResponse(reqExtendedSession);
}
/*
進(jìn)入編程會話,和上面的一模一樣
*/
void Demo2()
{
// 創(chuàng)建了一個進(jìn)入編程會話的“診斷請求變量”
diagRequest DoorFL.ProgrammingSession_Start reqProgSession;
// 創(chuàng)建一個變量代表診斷響應(yīng)返回的響應(yīng)碼
long respCode;
// 發(fā)送診斷請求
diagSendRequest(reqProgSession);
// 等待請求發(fā)送完畢
if(testWaitForDiagRequestSent(reqProgSession, 1000) == 1)
{
write("進(jìn)入編程會話的請求發(fā)送完畢");
}
else
{
write("進(jìn)入編程會話的請求發(fā)送失敗");
return;
}
// 等待收到診斷響應(yīng)
if(testWaitForDiagResponse(reqProgSession, 1000) == 1)
{
write("進(jìn)入編程會話的響應(yīng)已經(jīng)收到");
}
else
{
write("進(jìn)入編程會話的響應(yīng)未收到");
return;
}
// 獲取診斷響應(yīng)的響應(yīng)碼
respCode = diagGetLastResponseCode(reqProgSession);
if(respCode == -1) // 肯定響應(yīng)
{
write("進(jìn)入編程會話的響應(yīng)為肯定響應(yīng)");
}
else if(respCode == 0) // 未收到響應(yīng)
{
write("進(jìn)入編程會話的響應(yīng)還沒收到");
}
else
{
write("進(jìn)入編程會話的響應(yīng)為否定響應(yīng)桐臊,NRC為:0x%02X", respCode);
}
}
示例2:車窗位置百分比的寫入
/*
寫入車窗升降位置的百分比
*/
void Demo3_WriteWindowLift(){
diagRequest DoorFL.DID_WindowLiftRoughPosition_Write reqWindowLiftWrite;
/*
DiagSetPrimitiveByte —— 向診斷請求寓调,設(shè)置一個原始字節(jié),一般不會這么干
*/
// DiagSetPrimitiveByte(reqWindowLiftWrite, 0, 0x2E); // 將請求報(bào)文中第0個字節(jié)設(shè)置為0x2E
// DiagSetPrimitiveByte(reqWindowLiftWrite, 1, 0x02); // 將請求報(bào)文中第1個字節(jié)設(shè)置為0x02
// DiagSetPrimitiveByte(reqWindowLiftWrite, 2, 0x01); // 將請求報(bào)文中第2個字節(jié)設(shè)置為0x01
// DiagSetPrimitiveByte(reqWindowLiftWrite, 3, 0x06); // 將請求報(bào)文中第3個字節(jié)設(shè)置為0x06
/*
DiagSetParameterRaw —— 設(shè)置診斷請求中指定的參數(shù)的原始字節(jié)數(shù)組
*/
byte position[1] = {0x07};
//最后面這個1,是position的大小
diagSetParameterRaw(reqWindowLiftWrite,"WindowLiftRoughPosition",position,1);
//發(fā)送
diagSendRequest(reqWindowLiftWrite);
}
示例3:進(jìn)入擴(kuò)展會話狀態(tài)轩褐,并讀取響應(yīng)的參數(shù):當(dāng)前的會話類型猜绣、P2時間码秉、P2Ex時間
void Demo4_ExtendexSession()
{
diagRequest ExtendedDiagnosticSession_Start reqExtendedSession; // 創(chuàng)建一個診斷請求變量
long respCode; // 創(chuàng)建一個響應(yīng)碼變量
diagSendRequest(reqExtendedSession); // 發(fā)送診斷請求
if(1 != testWaitForDiagResponse(reqExtendedSession, 1000)) { // 等待收到診斷響應(yīng)
write("進(jìn)入擴(kuò)展會話的診斷請求赔蒲,未收到響應(yīng)!");
return;
}
respCode = diagGetLastResponseCode(reqExtendedSession);
if(-1 != respCode)
{
write("進(jìn)入擴(kuò)展會話的診斷請求力穗,收到了否定響應(yīng),否定響應(yīng)碼為0x%02X", respCode);
return;
}
write("進(jìn)入擴(kuò)展會話的診斷請求收到了肯定響應(yīng)");
/*
diagGetRespParameter —— 獲取診斷響應(yīng)中指定參數(shù)的值(數(shù)值气嫁、字符串)
*/
// {
// int sessionType; // 診斷響應(yīng)中返回的當(dāng)前會話類型
// int p2; // 診斷響應(yīng)中返回的常規(guī)超時時間(P2 Server Time)
// int p2ex; // 診斷響應(yīng)中返回的特殊超時時間(P2 extended Server Time)
//
// sessionType = diagGetRespParameter(reqExtendedSession, 1, "DiagSessionType");
// p2 = diagGetRespParameter(reqExtendedSession, 1, "P2");
// p2ex = diagGetRespParameter(reqExtendedSession, 1, "P2Ex");
// write("當(dāng)前的會話類型為:%d", sessionType);
// write("P2時間為:%dms", p2);
// write("P2Ex時間為:%dms", p2ex);
// }
/*
diagGetRespParameterRaw —— 獲取診斷響應(yīng)中指定參數(shù)的原始字節(jié)數(shù)組
*/
// {
// byte p2[2];
// int i;
//
// diagGetRespParameterRaw(reqExtendedSession, "P2", p2, elCount(p2));
// for(i=0; i < elCount(p2); i++)
// {
// write("診斷響應(yīng)中參數(shù)P2的第%d個字節(jié)的值為:0x%02X", i, p2[i]);
// }
// }
/*
DiagGetRespPrimitiveSize —— 獲取診斷響應(yīng)中的原始報(bào)文的字節(jié)數(shù)量
DiagGetRespPrimitiveByte —— 獲取診斷響應(yīng)中的原始報(bào)文中的指定索引上的字節(jié)
*/
{
int primitiveSize;
int i;
primitiveSize = DiagGetRespPrimitiveSize(reqExtendedSession);
write("診斷響應(yīng)的報(bào)文原始字節(jié)數(shù)量為:%d", primitiveSize);
for(i = 0; i < primitiveSize; i++)
{
byte b;
b = DiagGetRespPrimitiveByte(reqExtendedSession, i);
write("診斷響應(yīng)的原始報(bào)文中第%d個字節(jié)為0x%02X", i, b);
}
}
}
示例4:讀取DTC的列表:19 02服務(wù)
void Demo5_ReadDTC()
{
diagRequest DoorFL.FaultMemory_ReadAllIdentified reqReadDTC; // 創(chuàng)建一個診斷請求變量
int respCode; // 創(chuàng)建一個診斷響應(yīng)的響應(yīng)碼變量
// 設(shè)置讀取故障碼請求的故障碼狀態(tài)掩碼參數(shù)值為0x01
diagSetParameter(reqReadDTC, "DTCStatusMask", 0x01);
// 發(fā)送診斷請求
diagSendRequest(reqReadDTC);
// 等待直到收到診斷的響應(yīng)
if(1 != testWaitForDiagResponse(reqReadDTC, 1000))
{
write("讀取故障碼列表的診斷請求当窗,未收到響應(yīng)!");
return;
}
// 獲取診斷響應(yīng)的響應(yīng)碼
respCode = diagGetLastResponseCode(reqReadDTC);
if(-1 != respCode)
{
write("進(jìn)入擴(kuò)展會話的診斷請求寸宵,收到了否定響應(yīng)崖面,否定響應(yīng)碼為0x%02X", respCode);
return;
}
{
int dtcCount;
int i;
// 獲取診斷響應(yīng)中的指定的符合參數(shù)的參數(shù)值的個數(shù)
dtcCount = diagGetRespIterationCount(reqReadDTC, "ListOfDTC");
write("讀取故障碼請求的響應(yīng)報(bào)文中,返回的故障信息的數(shù)量:%d", dtcCount);
// 獲取診斷響應(yīng)中的每一組故障信息的參數(shù)值
for(i = 0; i < dtcCount; i++)
{
char dtcText[100];
long dtc;
int status;
diagGetComplexRespParameter(reqReadDTC, "ListOfDTC", i, "DTC", dtcText, elCount(dtcText));
dtc = diagGetComplexRespParameter(reqReadDTC, "ListOfDTC", i, "DTC");
status = diagGetComplexRespParameter(reqReadDTC, "ListOfDTC", i, "StatusOfDTC");
write("讀取到的第%d個故障信息的故障碼碼值為:0x%06X梯影,故障文本為:%s巫员,狀態(tài)碼為:0x%02X", i, dtc, dtcText, status);
}
}
}
示例5:解鎖ECU
void Demo6_UnlockECU()
{
/*
進(jìn)入到擴(kuò)展會話
*/
{
diagRequest DoorFL.ExtendedDiagnosticSession_Start reqExtendSession;
diagSendRequest(reqExtendSession); // 發(fā)送“進(jìn)入擴(kuò)展會話”的診斷請求
testWaitForDiagResponse(reqExtendSession, 1000); // 等到收到診斷的響應(yīng)
if(diagGetLastResponseCode() != -1)
{
write("進(jìn)入擴(kuò)展會話的診斷請求,未收到肯定響應(yīng)");
return;
}
}
/*
申請安全種子 --> 根據(jù)種子計(jì)算出Key -->發(fā)送Key來解鎖ECU
*/
{
diagRequest SeedLevel_0x01_Request reqGetSeed; // 獲取種子的請求
diagRequest KeyLevel_0x01_Send reqSendKey; // 發(fā)送Key的請求
byte seedArray[2];
byte keyArray[255];
dword keyActualSize;
int i;
diagSendRequest(reqGetSeed); // 發(fā)送“獲取安全種子”請求
testWaitForDiagResponse(reqGetSeed, 1000); // 等待收到診斷的響應(yīng)
if(diagGetLastResponseCode() != -1)
{
write("獲取安全種子的診斷請求甲棍,未收到肯定響應(yīng)");
return;
}
// 獲取響應(yīng)中返回的種子的字節(jié)數(shù)組
diagGetRespParameterRaw(reqGetSeed, "SecuritySeed", seedArray, elCount(seedArray));
write("獲取到的安全種子的字節(jié)為:0x%02X 0x%02X", seedArray[0], seedArray[1]);
// 根據(jù)種子計(jì)算出Key
diagGenerateKeyFromSeed(seedArray, elCount(seedArray), 1, "", "", keyArray, elCount(keyArray), keyActualSize);
write("生成的Key的字節(jié)數(shù):%d", keyActualSize);
write("生成的Key的字節(jié)為:");
for(i = 0; i < keyActualSize; i++)
{
write("\t0x%02X", keyArray[i]);
}
// 給“發(fā)送Key”的請求設(shè)置參數(shù)(SecurityKey)
diagSetParameterRaw(reqSendKey, "SecurityKey", keyArray, keyActualSize);
// 發(fā)送key的請求
diagSendRequest(reqSendKey);
}
}