怎么用Canoe CAPL发送诊断


前言

以UDS诊断为例,GMLAN会有些许差异,大同小异。
一般Canoe工程加载CDD以后,可以直接通过canoe工程的诊断界面,点击需要的诊断命令就可以发送诊断了。
在这里插入图片描述
那为什么还需要通过CAPL来发送诊断呢,
1.诊断界面的数据长度和有的参数范围是有限制(最大值最小值)的,但是如果你需要验证发送错误的长度或者超出范围的参数数据时ECU的响应是否符合要求的时候,没有办法通过诊断面板发送。
2.时间,可能你需要两个连续的诊断在间隔多长时间内发送,手动点击太慢。
或者你的ECU修复了某个bug软件升级之后,仅仅测试你修复的那个bug是不够的,最好把所有的诊断都测一下,一个一个点太慢,脚本测试才够快够准确。


1、直接调用CDD里的诊断发送

在CAPL里,诊断你也可以理解为一种类似于int这种的特殊数据类型。
关键字是diagRequest,前提是你的Canoe工程里有加载CDD.
在CAPL里编辑diagRequest,然后按空格,编译器会自动匹配你的canoe工程里加载的CDD名称。
在这里插入图片描述
选中CDD名字后,按‘.’,编译器会自动匹配出这个CDD支持的诊断列表,然后选中你要发送的诊断。
在这里插入图片描述
以要发送进入扩展层的诊断请求 10 03 为例,给这个诊断请求取个名字Diag_Tx_10_03,这样一个诊断请求的数据类型就定义好了。
在这里插入图片描述
定义完成以后,发送诊断请求的函数是diagSendRequest(diagRequest obj),括号里的参数就是我们定义的诊断请求。
那就是:

on key 't'
{
  diagSendRequest(Diag_Tx_10_03);
}

保存,编译,运行工程,点击按键t,
在这里插入图片描述
其他服务也是一样的,比如0x22服务的读SN的诊断

diagRequest Door.SerialNumber_Read Diag_Tx_ReadSN;

on key 's'
{
  diagSendRequest(Diag_Tx_ReadSN);
}

在这里插入图片描述

细心的同学可能会问,为什么Trace两个都是Tx,没有Rx,因为我手边暂时没有真实的ECU模块,是用的虚拟ECU,响应的数据是用另外一个节点模拟的,不过这不影响我们的测试验证,没有真实ECU的时候,想用验证就需要设置为模拟总线。
在这里插入图片描述

2、用报文的形式发送诊断

调用CDD里的诊断进行发送,最终体现在数据流里,还是以报文的形式发送出来的,所以也可以用发送报文的形式来发送诊断,只不过定义报文的请求ID要是诊断的请求id,而且诊断里的前2个byte决定了是单帧还是多帧,
如果是单帧,诊断里的第一个byte就代表者后续的有效字节长度。
如果是多帧,诊断里的第一个byte的低4位和第二个byte的高8位代表有效字节长度

比如发送进入扩展层的请求,发送的报文数据是02 10 03,其中的02就代表后面只有2个byte是有效数据位(10 03)。

如果不知道怎么用Canoe发送报文的同学,可以参考这个
链接: CAPL发送报文.

图片:

message 0x700 Diag_Tx_Request;

on key 't'
{
  Diag_Tx_Request.dlc=8;
  Diag_Tx_Request.byte(0)=0x02;
  Diag_Tx_Request.byte(1)=0x10;
  Diag_Tx_Request.byte(2)=0x03;
  output(Diag_Tx_Request);
}

3、怎么用CAPL发送多帧的诊断

ECU的诊断每帧最多只能发8byte的数据(CAN FD好像可以64byte),但是如果有个诊断要发送的数据超过了8byte的怎么办,那需要发送多帧数据才能完成一次发送了,而且多帧数据的发送是需要ECU端响应的,就是说

我上位机先发第一帧数据(首帧)给ECU端,
需要ECU给个响应(流控帧),
上位机才能接着发送后续数据帧(连续帧)。
在这里插入图片描述
比如说我需要发1,2,3,4,5,6,7,8,9,A共10个数据,一帧只能发8个,发不完。
1.我需要先发首帧,首字节的高4位是1才代表首帧,人家ECU收到这个之后才知道你一帧发不完需要多帧,才会发流控帧给你,让你有机会接着往下发
首帧如下:

0x10 0x0A 0x01 0x02 0x03 0x04 0x05 0x06
其中0x10的1代表首帧,00A代表有效数据长度,1,2,3,4,5,6是要发送的数据。

2.ECU回复个流控帧,第一个字节是0x30,上位机端接收到这个流控帧以后,才会接着发刚才没有发完的数据。
0x30 0x00 0x00 0x00 0x00 x00 0x00 0x00

3.上位机接着发后续数据帧(连续帧),连续帧的首字节的高4位是2,ECU端接收到2以后,就知道这个数据是跟上一帧连起来的。
0x21 0x07 0x08 0x09 0x0A
在这里插入图片描述

3.1监控流控帧后,把多帧数据自己分帧发送

假设我们通过发送报文的方式发送诊断里的F189,需要写的数据有13byte,加上0x2E 0xF1 0x89,就是16位,一帧发送不完,需要多帧发送。
第一步:向ECU发首帧
第二步:等待接收ECU端响应的流控帧
第三步:向ECU发送连续帧

那首帧里表示长度的就占据2个byte了(byte1的高4位代表帧类型,byte1的低4位和byte2的8位一起定义有效数据长度)

在这里插入图片描述
首帧应该这样发送,第一个0x10,高四位是1代表是首帧,第二个byte的0x10是代表后续的有效数据长度是16位。
0x10 0x10 0x2E 0xF1 0x89 0x00 0x00 0x00

发送完之后,需要等待ECU响应(回复流控帧0x30),才能接着往下发送后续数据帧(连续帧)。

on key 't'
{
  Diag_Tx_Request.dlc=8;
  Diag_Tx_Request.byte(0)=0x10;
  Diag_Tx_Request.byte(1)=0x10;
  Diag_Tx_Request.byte(2)=0x2E;
  Diag_Tx_Request.byte(3)=0xF1;
  Diag_Tx_Request.byte(4)=0x89;
  Diag_Tx_Request.byte(5)=0x00;
  Diag_Tx_Request.byte(6)=0x00;
  Diag_Tx_Request.byte(7)=0x00;
  output(Diag_Tx_Request);//先发首帧
  Flag_Multi_F189=1;
}

//0x600是ECU的响应ID,就是说接收到ID为0x600的报文以后就会触发下面这个函数
on message 0x600
{
  if(this.byte(0)==0x30)//看看第一个byte如果是0x30代表是流控帧,代表可以接着往下发送数据
  {
    if(Flag_Multi_F189)//判断是不是F189的流控帧
    {
      Flag_Multi_F189=0;
      Diag_Tx_Request.byte(0)=0x21;
      Diag_Tx_Request.byte(1)=0x00;
      Diag_Tx_Request.byte(2)=0x00;
      Diag_Tx_Request.byte(3)=0x00;
      Diag_Tx_Request.byte(4)=0x00;
      Diag_Tx_Request.byte(5)=0x00;
      Diag_Tx_Request.byte(6)=0x00;
      Diag_Tx_Request.byte(7)=0x00;
      output(Diag_Tx_Request);//连续帧一次发不完可以一直连续发
      
      Diag_Tx_Request.byte(0)=0x22;
      Diag_Tx_Request.byte(1)=0x00;
      Diag_Tx_Request.byte(2)=0x00;
      Diag_Tx_Request.byte(3)=0x00;
      output(Diag_Tx_Request);//连续帧一次发不完可以一直连续发,两个连续帧之间是否需要时间间隔是看流控帧返回的数据决定的,这里不展开讲了,有需要的可以留言,可以专门写一篇各个时间参数的
    }
  }
}
  

在这里插入图片描述
这是发送16个数据的多帧传输可以这样写。
如果要发送1000个byte呢,也可以这么写,不过会比较麻烦。

3.2调用CDD里的诊断发送

还是以发送诊断F189为例,可以参考上面介绍的调用CDD里的诊断发送的,但是发送的数据是诊断界面默认的数据,如下全0。
在这里插入图片描述
如果想用修改写入的数据需要调用函数

long diagSetParameterRaw (diagRequest obj, char parameterName[], byte* buffer, DWORD buffersize)

![在这里插入图片描述](https://img-blog.csdnimg.cn/bea9acad12b9495f8b7780868d852622.png
每个参数的描述如下

在这里插入图片描述
第一个参数 obj就是前面用diagrequest定义的那个变量,就是说你要发哪条诊断请求
第二个参数是你想写入的参数的修饰词qualifier,这个修饰词去哪里找呢,我理解去CDD文件里找才是最准确的,比如F189的这个参数修饰词就是Part_Number。(一般安装完Canoe后默认附带安装candelastudio的,可以直接双击点开CDD文件,查看CDD,编辑CDD的话还需要硬件license,但是查看是不用license的)
在这里插入图片描述
第三个参数就是你要写入的数据放到一个buffer里
第四个参数是buffer的长度.

如下,先定义diagrequest变量和要写入的数据buffer,再给写入的的诊断参数赋值,再发送诊断

byte ID_Write[13];
diagRequest Door.EcuIdentification_Write Diag_Tx_WriteID;

on key 'm'
{
  ID_Write[0]=0xff;
  ID_Write[1]=0x55;
  ID_Write[2]=0xAA;
  diagSetParameterRaw(Diag_Tx_WriteID,"Part_Number",ID_Write,13);
  diagSendRequest(Diag_Tx_WriteID);
}

在这里插入图片描述

3.3使用CanTp分包分帧发送

当你使用第一种报文的方式发送多帧的诊断时,有没有想过要是有个函数,我直接告诉多发多长的数据,然后把数据给他,让它自己发送就好了,这样就不用我自己在把数据分包了。

有的,cantp,我理解它的作用就是把这些数据按照协议打包/分包这种。

不过不是CAPL自带的函数,需要额外加载库,但是这个库是安装canoe的时候就有了的,
3.1:把安装目录下的dll文件拷贝到你的工程目录下。
在这里插入图片描述
3.2:在节点的配置Configuration选项里,选择Components,再选择Add添加osek_dp.dll文件
在这里插入图片描述
3.3在CAPL里选择添加osek_tp.dll文件,保存,这里".\osek_tp.dll"是相对路径,其中.\就代表你的工程文件路径,我的dll文件是直接放在工程目录下的
在这里插入图片描述
在这里插入图片描述
3.4.点击保存CAPL文件以后你会发现在CAPL编辑器的右侧多了osek_tp.dll,点击+展开以后,会看到这个dll库里支持的函数,它给你开放了好多函数接口,前面includes了之后,你就可以用这些函数了,就像编辑器自带的函数一样。
在这里插入图片描述
3.5那怎么用这个库里面的函数呢,函数很多,大部分我也不懂什么意思,
不过了解几个能够发送消息的函数就够用了,其他的大家可以自己去尝试。
要用cantp发送函数,分几步
第一步:先连接
用的函数是CanTpCreateConnection(),我理解这一步的作用就是先确定是标准帧还是扩展帧。
在这里插入图片描述
第二步:设置ID
设置发送请求的ID和ECU响应的ID
在这里插入图片描述
第三步发送数据
在这里插入图片描述
这几步里都会用一个connhandle,就是在第一步建立连接的时候返回的一个数据吧,就是说无论干啥都要建立在连接ok的基础上才可以。。
第一个参数是句柄,建立连接后得到的,
第二个参数是你要发送的数据
第3个数据是你要发送的数据长度

我们还是以发送诊断F189为例
在这里插入图片描述

代码如下

includes
{
   #pragma library (".\osek_tp.dll")
}

variables
{
    const dword Diag_Tx_id = 0x700;
    const dword Diag_Rx_id = 0x600;
    const byte  TpPadding =  0x55;

    byte ID_Write[16];
    long TpHandle;
}
on start
{
    TpHandle = CanTpCreateConnection(0); //连接,参数是0代表标准帧
    CanTpSetTxIdentifier(TpHandle, Diag_Tx_id); //设置ID
    CanTpSetRxIdentifier(TpHandle, Diag_Rx_id);  
    CanTpSetPadding(TpHandle, TpPadding);//设置填充位
}

on key 't'
{
 ID_Write[0]=0x2E;
 ID_Write[1]=0xF1; 
 ID_Write[2]=0x89;
 ID_Write[3]=0x33; //想用发送什么数据,给要发送的数组赋值就好了,我这里随便举例一个数据
 CanTpSendData(TpHandle, ID_Write, 16);//发送
}

建立连接,设置id这些只需要做一次就好了,所以放在on start里在工程运行的时候设置一次就好了。
还多了一个函数CanTpSetPadding
这个函数的意思是,
比如当你发送一帧数据时,02 10 03只有3个byte,但是一帧里需要发满8个byte的时候(有的车厂就有这样的要求),后面5个byte其实是没有意义的,可以随便填充,但是有的车厂会要求填充0xAA或0x55…
CanTpSetPadding这个函数就是设置填充数据的,车厂没有要求的话可以不用这个.

看下面的数据,填充0x55的那几位,就是最后一帧连续帧里有效数据为不够8位了,需要填充。在这里插入图片描述

  • 94
    点赞
  • 617
    收藏
    觉得还不错? 一键收藏
  • 84
    评论
### 回答1: Canoe CAPL编程实例包括很多方面,例如网络通讯、数据传输、故障诊断和测试等。其中有一些比较典型的例子如下: 1、网络通讯实例: 在Canoe CAPL编程中,可以使用CAPL库函数对网络进行通讯。通过发送CAN消息可以在网络中进行数据的传输。例如,在测试中,我们可以模拟发送一条CAN消息,并且在接收到回传消息后进行判断,可以通过判断结果来进行测试。 2、数据传输实例: Canoe CAPL编程可以方便地进行数据的传输。例如,可以对多个CAN信号进行检测和处理,可以通过处理之后得到特定的数据内容。此外,还可以进行多种格式的数据处理,例如对BCD码、二进制码、十六进制码等进行解析。 3、故障诊断实例: Canoe CAPL编程可以实现对网络故障的诊断,通过在网络中发送和接收命令,可以进行网络的测试和检测,确保网络的健康。例如,在接收数据时,如果出现错误信息,则可以判断出网络出现了故障。 4、测试实例: Canoe CAPL编程也可以进行测试。例如,在汽车制造中,可以验证CAN网络的正确性,对CAN总线上的数据进行检查,以确保汽车的安全性。另外,还可以模拟传感器、控制单元等,以检测其他部件的正确性。 总之,Canoe CAPL编程实例是非常广泛的,包括了很多方面的内容,通过对这些实例进行学习和应用,可以达到更好地进行数据处理、网络通讯、故障诊断和测试的目的。 ### 回答2: Canoe CAPL编程是面向嵌入式系统的一种高级编程语言,能够帮助开发者进行控制单元的软件开发、测试和调试等工作。下面就介绍一下Canoe CAPL编程的实例。 我们可以通过Canoe CAPL编程来控制汽车中的某些功能模块,例如车门、车窗、车灯、音响等。可以编写一系列的函数,通过向不同的功能模块发送信号,来控制它们的状态。比如,我们可以定义一个函数,来控制车门的状态。通过编写如下代码: on key 'F4' { setDoorState(1); //打开车门 } on key 'F5' { setDoorState(0); //关闭车门 } void setDoorState(int state) { if(state == 1) { setSignal(DOOR_SIGNAL, 1); //发送打开车门的信号 } else { setSignal(DOOR_SIGNAL, 0); //发送关闭车门的信号 } } 在这个代码中,我们首先定义了两个按键,用来控制车门的状态。当用户按下F4键时,调用setDoorState函数,将车门打开;当用户按下F5键时,调用setDoorState函数,将车门关闭。setDoorState函数根据传入的状态参数,向DOOR_SIGNAL信号发送对应的数值(1为打开车门,0为关闭车门),从而实现控制车门状态的功能。 另外,Canoe CAPL编程还可以用于信号的模拟和调试。在开发过程中,我们可以通过编写一些模拟代码,来模拟接收到不同数据信号的情况,并进行相关的处理。这样就可以将信号的处理过程模拟出来,提前发现并解决潜在的问题。 总之,Canoe CAPL编程可以帮助汽车系统开发者快速地开发出控制单元的软件,并进行测试和调试,是一种非常实用的编程语言。 ### 回答3: Canoe CAPL编程实例是指用Vector公司的CANoe工具编写以CAPL语言为基础的程序来控制CANape的功能。 CANoe是一款用于开发、测试和分析基于CAN总线的系统的软件工具,支持多种总线,如CAN、LIN和FlexRay等。CAPLCANoe中一种专门用于CAN总线开发的高级编程语言,广泛应用于CAN总线控制程序的编写和测试。 一个典型的Canoe CAPL编程实例是用CAPL语言编写一个简单的CAN总线消息接收程序。该程序可以接收从CAN总线上发送过来的CAN消息,并将其显示在CANoe的消息窗口中。 这个程序的实现步骤如下: 1.定义变量:定义一个变量来保存接收到的CAN总线消息。 2.定义事件:通过事件触发来处理CAN总线消息。 3.创建回调函数:定义一个回调函数,用来处理CAN总线上接收到的消息,并将其保存到变量中。 4.初始化事件:初始化事件,以便接收CAN总线上的信息,然后在事件处理程序中调用回调函数。 5.启动测试:启动CANoe测试后,该程序就可以在CAN总线上接收消息并将其显示在CANoe的消息窗口中了。 总之,Canoe CAPL编程实例是一个重要的工具,可以帮助工程师们更好地开发、测试和分析CAN总线系统,从而提高生产效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 84
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值