带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)

欢迎大家学习我的《带你玩转车载测试——CAPL入门篇》系列课程,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。

学习过程中如有任何疑问,可底下评论!

如果觉得文章内容在工作学习中有帮助到你,麻烦点赞收藏评论+关注走一波!感谢各位的支持!

1. 诊断库函数

        CANoe中的诊断库函数主要有两类:一类是依据CDD文件使用的函数;另一类是依据传输层动态库(cantp.dll)来实现诊断功能的函数。第一类函数的使用需要制作完整的CDD文件,适用于编程能力一般且简单地诊断场合,而第二类函数通过cantp.dll来实现诊断,对编程能力有一定的要求,适用于复杂的诊断场合,如flash流程。后续M哥将对两种形式的诊断库函数分别介绍,今天先来介绍基于CDD文件的诊断库函数。

1.1 通信和设定函数(Communication and Setup)

       常用函数如下表1所示:

表1 Communication and Setup
函数名 功能
diagSetTarget 设置诊断的目标ECU
diagSendRequest 向目标ECU发送诊断请求
diagStartTesterPresent 向目标ECU开始发送TesterPresent请求
diagStopTesterPresent 向目标ECU开始发送TesterPresent请求
diagSendFunctional 向目标ECU发送功能寻址诊断请求
diagSetTimeout 设定诊断请求超时时间
diagSetTimeoutHandle 创建回调函数用于诊断请求超时调用

(1)diagSetTarget:用于设置诊断的目标ECU名,使之与目标ECU建立诊断通信,其参数为ECU名,即CDD文件中的 “ECU qulifier”,如下图所示:

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第1张图片

 下面代码表示当按下‘b’键时,所建立的目标ECU是否正确:

on key 'b'
{
  if( 0 == diagSetTarget( "Vector_Seat")) 
    write( "Correct setting target!");
}

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第2张图片

(2)diagSendRequest:向目标ECU发送诊断请求,比如:按下按键‘b’,发送进入拓展会话请求;

includes
{
  
}

variables
{
  diagRequest Vector_Seat.ExtendedDiagnosticSession_Start ExtendSessionReq;
}

on key 'b'
{
  long ret;
  ret = diagSendRequest(ExtendSessionReq);
  
  if(ret == 0){
    write("Request Succeed!");
  }
}

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第3张图片

 (3)diagStartTesterPresent和diagStopTesterPresent: 用于向设定目标ECU发送/停止TesterPresent请求,如按下按键‘a’,发送TesterPresent请求,按下按键‘b’,停止TesterPresent请求;

includes
{
  
}

variables
{

}

on key 'a'
{
  long ret;
  ret = diagStartTesterPresent("Vector_Seat");

  if(ret == 0){
    write("发送TesterPresent请求!");
  }
}

on key 'b'
{
  long ret;
   ret = diagStopTesterPresent("Vector_Seat");
  
  if(ret == 0){
    write("停止TesterPresent请求!");
  }
}

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第4张图片

(4) diagSendFunctional:上述diagSendRequest向目标ECU发送请求是以物理寻址的方式,而diagSendFunctional则是以功能寻址的方式向ECU发送请求(功能寻址ID:0x750),如下所示:

includes
{
  
}

variables
{
  diagRequest Vector_Seat.ExtendedDiagnosticSession_Start ExtendSessionReq;
}

on key 'a'
{
  long ret;
  ret = diagSendFunctional(ExtendSessionReq);

  if(ret == 0){
    write("功能寻址请求进入拓展会话!");
  }
}

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第5张图片

(5)diagSetTimeout和diagSetTimeoutHandle:这两个函数主要用于诊断请求超时设置及其超时处理,进行超时处理时是通过回调函数的方式进行执行,如下所示:

variables
{
  
}

on start
{
  diagSetTimeout (10); // Set timeout to 200 ms
  diagSetTimeoutHandler("Request_Timeout");
}

on key 'a'
{
  diagRequest Vector_Seat.ExtendedDiagnosticSession_Start ExtendSessionReq;
  diagSendRequest(ExtendSessionReq);
}

void Request_Timeout()
{
  write("No response received within expected time frame!");
}

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第6张图片

 1.2 Miscellaneous库函数

      Miscellaneous库函数通常为安全访问函数,常用的如下所示:

表2 Miscellaneous库函数
函数名 功能
diagGenerateKeyFromSeed 通过种子计算生成密钥
diagSetCurrentSession 用于设置ECU当前的诊断会话
diagStartGenerateKeyFromSeed 通过种子计算生成密钥
_Diag_GenerateKeyResult 返回diagStartGenerateKeyFromSeed计算出的密钥结果

(1)diagGenerateKeyFromSeed:此函数主要通过CDD中添加的seed_key.dll文件来计算ECU解锁密钥并返回计算结果,一般用于test module模块,如下:

includes
{
  
}

variables
  {
    //actual size of Seed and Key Arrays depend on ECU
    byte gSeedArray[2];
    int gSeedArraySize = 2;
    int gSecurityLevel = 0x01;
    char gVariant[200] = "Variant1";
    char gOption[200] = "option";
    byte gKeyArray[2];
    int gMaxKeyArraySize = 2;
    dword gActualSizeOut = 2;
    char gDebugBuffer[2000];
    diagRequest DoorFL.ExtendedDiagnosticSession_Start gExtendSessionReq;
    diagRequest DoorFL.SeedLevel_0x01_Request gSeedReq;
    diagResponse DoorFL.SeedLevel_0x01_Request gSeedResp;
    diagRequest DoorFL.KeyLevel_0x01_Send gKeyReq;
  }

//Unlock ECU by calling customer specific SeedKey DLL (e.g. in a CAPL test module)
testcase UnlockEcu()
{
  long ret;
  diagSendRequest(gExtendSessionReq);
  //Request seed from ECU
  diagSendRequest(gSeedReq);
  //Wait until request has been sent completely
  testWaitForDiagRequestSent(gSeedReq, 1000); //Wait for response and write seed from response parameter to array
  testWaitForDiagResponse(gSeedReq, 1000);
  diagGetLastResponse (gSeedReq, gSeedResp);
  diagGetParameterRaw (gSeedResp, "SecuritySeed", gSeedArray, elcount(gSeedArray)); //Calculate key
  ret = diagGenerateKeyFromSeed ( gSeedArray, gSeedArraySize, gSecurityLevel, gVariant, gOption, gKeyArray, gMaxKeyArraySize, gActualSizeOut);
  if( 0 == ret) //diagGenerateKeyFromSeed successful
  {
    //Write result to diagnostic request
    diagSetParameterRaw(gKeyReq, "SecurityKey", gKeyArray, gActualSizeOut);
    //Send Key to unlock ECU
    gKeyReq.SendRequest();
    testWaitForDiagRequestSent(gKeyReq, 1000);
  }
}

void MainTest ()
{
  UnlockEcu();
}

带你玩转车载测试——CAPL入门篇六:CAPL常用库函数介绍(二)_第7张图片

(2)diagSetCurrentSession:用于设定ECU的当前诊断会话。

(3)diagStartGenerateKeyFromSeed和_Diag_GenerateKeyResult:diagStartGenerateKeyFromSeed函数用来计算生成的密钥,而密钥计算的结果通过回调函数_Diag_GenerateKeyResult来返回,如下所示:

_Diag_GenerateKeyResult( long result, BYTE computedKey[])
{
  diagRequest DoorFL.SeedLevel_0x01_Request rqSendKey;

  if( 0 != result)
  {
    write( "Error: computing key returned %d", result);
    return;
  }

  // Success, i.e. a key was computed, so send it to the ECU

  rqSendKey.SetParameterRaw( "SecurityKey", computedKey, elcount(computedKey));
  rqSendKey.SendRequest();
}

on diagResponse DoorFL.SeedLevel_0x01_Request
{
  BYTE seed[2];
  long count;

  count = this.GetParameterRaw( "SecuritySeed", seed, elcount(seed));
  diagStartGenerateKeyFromSeed(seed, elcount( seed), 1, "variant", "option");
}

on key 'u' // unlock
{
  diagRequest DoorFL.ExtendedDiagnosticSession_Start ExtendReq;
  diagRequest DoorFL.SeedLevel_0x01_Request rqRequestSeed;
  ExtendReq.SendRequest();
  rqRequestSeed.SendRequest();
}

由于诊断库函数众多,后续将继续进行讲述,敬请期待............

感谢对本期内容不遗余力的学习,下期内容即将奉上,欢迎下次光临!

你可能感兴趣的:(开发语言,测试工具,汽车,网络,mcu)