CAPL針對(duì)ECU的診斷,提供了一些基本的函數(shù):

image.png

image.png

image.png
下面結(jié)合TestModule 和 診斷的函數(shù),完成ECU的自動(dòng)化測(cè)試
示例1:通過診斷的10服務(wù),進(jìn)行會(huì)話的切換測(cè)試
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ò)展會(huì)話
*/
void demo1(){
// 創(chuàng)建了一個(gè)進(jìn)入擴(kuò)展會(huì)話的“診斷請(qǐng)求變量”
diagRequest DoorFL.ExtendedDiagnosticSession_Start reqExtendedSession;
// 創(chuàng)建一個(gè)變量代表診斷響應(yīng)返回的響應(yīng)碼
long respCode;
//發(fā)送請(qǐng)求
diagSendRequest(reqExtendedSession);
//等待請(qǐng)求發(fā)送完畢
if(testWaitForDiagRequestSent(reqExtendedSession, 1000) == 1)
{
write("進(jìn)入擴(kuò)展會(huì)話的請(qǐng)求發(fā)送完畢");
}
else
{
write("進(jìn)入擴(kuò)展會(huì)話的請(qǐng)求發(fā)送失敗");
return;
}
//等待接收到診斷的響應(yīng)
if(testWaitForDiagResponse(reqExtendedSession,1000) == 1){
write("進(jìn)入擴(kuò)展會(huì)話的響應(yīng)已經(jīng)收到");
}
else
{
write("進(jìn)入擴(kuò)展會(huì)話的響應(yīng)未收到");
return;
}
respCode = diagGetLastResponseCode(reqExtendedSession);
if(respCode == -1) // 肯定響應(yīng)
{
write("進(jìn)入擴(kuò)展會(huì)話的響應(yīng)為肯定響應(yīng)");
}
else if(respCode == 0) // 未收到響應(yīng)
{
write("進(jìn)入擴(kuò)展會(huì)話的響應(yīng)還沒收到");
}
else
{
write("進(jìn)入會(huì)展會(huì)話的響應(yīng)為否定響應(yīng),NRC為:0x%02X", respCode);
}
//把信息寫入報(bào)告中;
testReportWriteDiagResponse(reqExtendedSession);
}
/*
進(jìn)入編程會(huì)話,和上面的一模一樣
*/
void Demo2()
{
// 創(chuàng)建了一個(gè)進(jìn)入編程會(huì)話的“診斷請(qǐng)求變量”
diagRequest DoorFL.ProgrammingSession_Start reqProgSession;
// 創(chuàng)建一個(gè)變量代表診斷響應(yīng)返回的響應(yīng)碼
long respCode;
// 發(fā)送診斷請(qǐng)求
diagSendRequest(reqProgSession);
// 等待請(qǐng)求發(fā)送完畢
if(testWaitForDiagRequestSent(reqProgSession, 1000) == 1)
{
write("進(jìn)入編程會(huì)話的請(qǐng)求發(fā)送完畢");
}
else
{
write("進(jìn)入編程會(huì)話的請(qǐng)求發(fā)送失敗");
return;
}
// 等待收到診斷響應(yīng)
if(testWaitForDiagResponse(reqProgSession, 1000) == 1)
{
write("進(jìn)入編程會(huì)話的響應(yīng)已經(jīng)收到");
}
else
{
write("進(jìn)入編程會(huì)話的響應(yīng)未收到");
return;
}
// 獲取診斷響應(yīng)的響應(yīng)碼
respCode = diagGetLastResponseCode(reqProgSession);
if(respCode == -1) // 肯定響應(yīng)
{
write("進(jìn)入編程會(huì)話的響應(yīng)為肯定響應(yīng)");
}
else if(respCode == 0) // 未收到響應(yīng)
{
write("進(jìn)入編程會(huì)話的響應(yīng)還沒收到");
}
else
{
write("進(jìn)入編程會(huì)話的響應(yīng)為否定響應(yīng),NRC為:0x%02X", respCode);
}
}
示例2:車窗位置百分比的寫入
/*
寫入車窗升降位置的百分比
*/
void Demo3_WriteWindowLift(){
diagRequest DoorFL.DID_WindowLiftRoughPosition_Write reqWindowLiftWrite;
/*
DiagSetPrimitiveByte —— 向診斷請(qǐng)求,設(shè)置一個(gè)原始字節(jié),一般不會(huì)這么干
*/
// DiagSetPrimitiveByte(reqWindowLiftWrite, 0, 0x2E); // 將請(qǐng)求報(bào)文中第0個(gè)字節(jié)設(shè)置為0x2E
// DiagSetPrimitiveByte(reqWindowLiftWrite, 1, 0x02); // 將請(qǐng)求報(bào)文中第1個(gè)字節(jié)設(shè)置為0x02
// DiagSetPrimitiveByte(reqWindowLiftWrite, 2, 0x01); // 將請(qǐng)求報(bào)文中第2個(gè)字節(jié)設(shè)置為0x01
// DiagSetPrimitiveByte(reqWindowLiftWrite, 3, 0x06); // 將請(qǐng)求報(bào)文中第3個(gè)字節(jié)設(shè)置為0x06
/*
DiagSetParameterRaw —— 設(shè)置診斷請(qǐng)求中指定的參數(shù)的原始字節(jié)數(shù)組
*/
byte position[1] = {0x07};
//最后面這個(gè)1,是position的大小
diagSetParameterRaw(reqWindowLiftWrite,"WindowLiftRoughPosition",position,1);
//發(fā)送
diagSendRequest(reqWindowLiftWrite);
}
示例3:進(jìn)入擴(kuò)展會(huì)話狀態(tài),并讀取響應(yīng)的參數(shù):當(dāng)前的會(huì)話類型、P2時(shí)間、P2Ex時(shí)間
void Demo4_ExtendexSession()
{
diagRequest ExtendedDiagnosticSession_Start reqExtendedSession; // 創(chuàng)建一個(gè)診斷請(qǐng)求變量
long respCode; // 創(chuàng)建一個(gè)響應(yīng)碼變量
diagSendRequest(reqExtendedSession); // 發(fā)送診斷請(qǐng)求
if(1 != testWaitForDiagResponse(reqExtendedSession, 1000)) { // 等待收到診斷響應(yīng)
write("進(jìn)入擴(kuò)展會(huì)話的診斷請(qǐng)求,未收到響應(yīng)!");
return;
}
respCode = diagGetLastResponseCode(reqExtendedSession);
if(-1 != respCode)
{
write("進(jìn)入擴(kuò)展會(huì)話的診斷請(qǐng)求,收到了否定響應(yīng),否定響應(yīng)碼為0x%02X", respCode);
return;
}
write("進(jìn)入擴(kuò)展會(huì)話的診斷請(qǐng)求收到了肯定響應(yīng)");
/*
diagGetRespParameter —— 獲取診斷響應(yīng)中指定參數(shù)的值(數(shù)值、字符串)
*/
// {
// int sessionType; // 診斷響應(yīng)中返回的當(dāng)前會(huì)話類型
// int p2; // 診斷響應(yīng)中返回的常規(guī)超時(shí)時(shí)間(P2 Server Time)
// int p2ex; // 診斷響應(yīng)中返回的特殊超時(shí)時(shí)間(P2 extended Server Time)
//
// sessionType = diagGetRespParameter(reqExtendedSession, 1, "DiagSessionType");
// p2 = diagGetRespParameter(reqExtendedSession, 1, "P2");
// p2ex = diagGetRespParameter(reqExtendedSession, 1, "P2Ex");
// write("當(dāng)前的會(huì)話類型為:%d", sessionType);
// write("P2時(shí)間為:%dms", p2);
// write("P2Ex時(shí)間為:%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個(gè)字節(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個(gè)字節(jié)為0x%02X", i, b);
}
}
}
示例4:讀取DTC的列表:19 02服務(wù)
void Demo5_ReadDTC()
{
diagRequest DoorFL.FaultMemory_ReadAllIdentified reqReadDTC; // 創(chuàng)建一個(gè)診斷請(qǐng)求變量
int respCode; // 創(chuàng)建一個(gè)診斷響應(yīng)的響應(yīng)碼變量
// 設(shè)置讀取故障碼請(qǐng)求的故障碼狀態(tài)掩碼參數(shù)值為0x01
diagSetParameter(reqReadDTC, "DTCStatusMask", 0x01);
// 發(fā)送診斷請(qǐng)求
diagSendRequest(reqReadDTC);
// 等待直到收到診斷的響應(yīng)
if(1 != testWaitForDiagResponse(reqReadDTC, 1000))
{
write("讀取故障碼列表的診斷請(qǐng)求,未收到響應(yīng)!");
return;
}
// 獲取診斷響應(yīng)的響應(yīng)碼
respCode = diagGetLastResponseCode(reqReadDTC);
if(-1 != respCode)
{
write("進(jìn)入擴(kuò)展會(huì)話的診斷請(qǐng)求,收到了否定響應(yīng),否定響應(yīng)碼為0x%02X", respCode);
return;
}
{
int dtcCount;
int i;
// 獲取診斷響應(yīng)中的指定的符合參數(shù)的參數(shù)值的個(gè)數(shù)
dtcCount = diagGetRespIterationCount(reqReadDTC, "ListOfDTC");
write("讀取故障碼請(qǐng)求的響應(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個(gè)故障信息的故障碼碼值為:0x%06X,故障文本為:%s,狀態(tài)碼為:0x%02X", i, dtc, dtcText, status);
}
}
}
示例5:解鎖ECU
void Demo6_UnlockECU()
{
/*
進(jìn)入到擴(kuò)展會(huì)話
*/
{
diagRequest DoorFL.ExtendedDiagnosticSession_Start reqExtendSession;
diagSendRequest(reqExtendSession); // 發(fā)送“進(jìn)入擴(kuò)展會(huì)話”的診斷請(qǐng)求
testWaitForDiagResponse(reqExtendSession, 1000); // 等到收到診斷的響應(yīng)
if(diagGetLastResponseCode() != -1)
{
write("進(jìn)入擴(kuò)展會(huì)話的診斷請(qǐng)求,未收到肯定響應(yīng)");
return;
}
}
/*
申請(qǐng)安全種子 --> 根據(jù)種子計(jì)算出Key -->發(fā)送Key來解鎖ECU
*/
{
diagRequest SeedLevel_0x01_Request reqGetSeed; // 獲取種子的請(qǐng)求
diagRequest KeyLevel_0x01_Send reqSendKey; // 發(fā)送Key的請(qǐng)求
byte seedArray[2];
byte keyArray[255];
dword keyActualSize;
int i;
diagSendRequest(reqGetSeed); // 發(fā)送“獲取安全種子”請(qǐng)求
testWaitForDiagResponse(reqGetSeed, 1000); // 等待收到診斷的響應(yīng)
if(diagGetLastResponseCode() != -1)
{
write("獲取安全種子的診斷請(qǐng)求,未收到肯定響應(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”的請(qǐng)求設(shè)置參數(shù)(SecurityKey)
diagSetParameterRaw(reqSendKey, "SecurityKey", keyArray, keyActualSize);
// 發(fā)送key的請(qǐng)求
diagSendRequest(reqSendKey);
}
}