CAPL之ECU的診斷自動化

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


image.png

image.png

image.png

下面結(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);
  }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末简识,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌七扰,老刑警劉巖奢赂,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颈走,居然都是意外死亡膳灶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門立由,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轧钓,“玉大人,你說我怎么就攤上這事拆吆×” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵枣耀,是天一觀的道長霉晕。 經(jīng)常有香客問我,道長捞奕,這世上最難降的妖魔是什么牺堰? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮颅围,結(jié)果婚禮上伟葫,老公的妹妹穿的比我還像新娘。我一直安慰自己院促,他們只是感情好筏养,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著常拓,像睡著了一般渐溶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弄抬,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天茎辐,我揣著相機(jī)與錄音,去河邊找鬼掂恕。 笑死拖陆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的懊亡。 我是一名探鬼主播依啰,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼店枣!你這毒婦竟也來了孔飒?” 一聲冷哼從身側(cè)響起灌闺,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坏瞄,沒想到半個月后桂对,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸠匀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年蕉斜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缀棍。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡宅此,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出爬范,到底是詐尸還是另有隱情父腕,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布青瀑,位于F島的核電站璧亮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏斥难。R本人自食惡果不足惜枝嘶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哑诊。 院中可真熱鬧群扶,春花似錦、人聲如沸镀裤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽暑劝。三九已至馁菜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铃岔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工峭火, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毁习,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓卖丸,卻偏偏與公主長得像纺且,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子稍浆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容