CAPL之ECU的診斷自動(dòng)化

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);
  }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容