CAN请求消息2E SID的CAPL多帧处理



我正试图找到一个答案,在那里我可以使用SID 2E UDS诊断的CAPL程序读取请求消息的流控制。我在服务器端实现了ISOTP协议,用于传输多帧响应消息,运行良好。

我添加了以下CAPL程序供您参考。现在我的问题是,我想编写一个CAPL程序,它的工作方式类似于客户端请求消息。我添加了一些键来触发请求消息。由于我在请求消息时无法接收流控制FC和CF连续帧。我在diganostics面板中没有CDD文件可供配置。

请有人帮我解决这个问题。至少举一个例子会非常感激。

/*@!Encoding:1252*/
includes
{

}
variables
{
//Golbal variables declaration
msTimer timer_DIAG;
byte checkByte0;  
message 0x713 msg = { dlc=8}; //0x713 request msg Need help to fix when SID 2E is requested 
byte check_byte0;
message 0x71B sendmsg; //0x71B response msg
}
//Request message from client to server 0x713 CAN ID 
on message 0x713
{
//  tester_DiagReqEds = this.tester_DiagReqEds;
//  write(" Request CAN msg 0x723 Received %x", tester_DiagReqEds);
checkByte0 = this.byte(0) & 0x30;  
if(checkByte0 == 0x30) //FC frame
{
msg.dlc = 8;
msg.dword(0) = 0x30;
msg.dword(4) = 0x00;    
output(msg);
}
}
//send request write data by identifier 2E F190 parameters
on key 'q'
{  
msg.byte(0) = 0x09;
msg.byte(1) = 0x2E;
msg.byte(2) = 0xF1;
msg.byte(3) = 0x90;
msg.byte(4) = 0x10;
msg.byte(5) = 0x20;
msg.byte(6) = 0x30;
msg.byte(7) = 0x40;
msg.byte(8) = 0x01;
msg.byte(9) = 0x02;
msg.byte(10) = 0x03;
output(msg);  
}
//send request read data by identifier 22 F190 parameters below 8 bytes which is working fine
on key 'e'
{
msg.byte(0) = 0x03;
msg.byte(1) = 0x2E;
msg.byte(2) = 0xF1;
msg.byte(3) = 0x90;
msg.byte(4) = 0x10;
msg.byte(5) = 0x20;
msg.byte(6) = 0x00;
msg.byte(7) = 0x00;
output(msg);

}
//send request to read data by identifier 22 F190 parameters working fine
on key 'w'
{
msg.byte(0) = 0x03;
msg.byte(1) = 0x22;
msg.byte(2) = 0xF1;
msg.byte(3) = 0x90;
msg.byte(4) = 0x00;
msg.byte(5) = 0x00;
msg.byte(6) = 0x00;
msg.byte(7) = 0x00;
output(msg);

}
//response message for flow control frame
on message 0x71B
{
//  checkByte0 = this.byte(0) & 0x30;
//  
//  if(checkByte0 == 0x10)
//  {
//    sendmsg.dword(0) = 0x30;
//    sendmsg.dword(4) = 0x00;
//    output(sendmsg);
//  }
}

你想发送有效载荷

2E F1 90 10 20 30 40 50 60 70

使用ISO TP。

为此,您必须遵循ISO-TP规范,并将数据分割为一个第一帧和(可能是几个)

连续帧这些帧应该看起来像:

第一帧:10 0A 2E F1 90 10 20 30

连续帧:21 40 50 60 70 00 00 00

说明:

10 0A 2E F1 90 10 20 30:

  • 1在第一个半字节中意味着,这是第一个帧
  • CCD_ 5之后的三个半字节包含有效载荷的长度。您想要发送10个字节,因此0x00A个字节

之后,第一帧包含有效负载的前6个字节。

21 40 50 60 70 00 00 00:

  • 2在第一个半字节中意味着,这是一个连续帧
  • 第二个半字节中的1意味着,这是第一个连续帧,第二个将具有2,依此类推

之后是接下来的7个字节的有效负载。

在CAPL代码中,这看起来像:

on key 'q'
{  
msg.byte(0) = 0x10;
msg.byte(1) = 0x0A
msg.byte(2) = 0x2E;
msg.byte(3) = 0xF1;
msg.byte(4) = 0x90;
msg.byte(5) = 0x10;
msg.byte(6) = 0x20;
msg.byte(7) = 0x30;
output(msg);  
}
on message 0x713
{
checkByte0 = this.byte(0) & 0x30;  
if(checkByte0 == 0x30) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;    
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
}

所以你要做的是:

发送第一帧,等待流量控制帧,发送连续帧。

同样,不需要手动执行此操作。CANoe附带了CanTp的实现。IIRC,CANoe提供了一个名为";CanTp";或";IsoTp";。没有必要使用客户尽职调查。

顺便说一下;客户端";以及";服务器";在ISOTP中。当您在服务器端有一个有效的实现时,您可以简单地在客户端使用相同的逻辑。

@斯皮勒先生,谢谢你的详细解释。正如你所解释的,我已经尝试过了,但当我收到CAN请求后面跟着capl代码的字节时,我感到困惑。下面我添加代码,我收到CANOe的请求。我想知道,我是否错过了一些需要添加代码到服务器以读取CANOe请求的东西。目前,CANOe并没有发送多帧,因为它正在寻找来自服务器(FC)的响应消息。请告诉我问题出在哪里?

/* just for underestanding Where 
#define ISOTP_SF        0x00        /* single frame */
#define ISOTP_FF        0x10        /* first frame */
#define ISOTP_CF        0x20        /* consecutive frame */
#define ISOTP_FC        0x30        /* flow control */
CanData[8] = {0,0,0,0,0,0,0,0}
for(dtcnt=0; dtcnt<RxCAN->DLC; dtcnt++)
{
CanData[dtcnt]= RxCAN->Data[dtcnt];
}*/
switch((uint16_t)RxCAN->StdId){
case TESTER_FUNC: //CAN 0x713 Rq
{
/*Request message from CAN to Diagnostic*/                  
/*If Isotp Single frame  == 0 then read 8 byte data */
dgiIsoTp.IsoTpFrameTypeRcv = (0xF0 & CanData[0]);
if (dgiIsoTp.IsoTpFrameTypeRcv == ISOTP_SF) 
{
//Function to read CAN request message flow control                       
ReadCanMsgfrom_Tester(CanData, TESTER_FUNC);
}
else if(dgiIsoTp.IsoTpFrameTypeRcv == ISOTP_FF)
{
if (TimeOutTickFFtoFC_Enable == 1)
{
TimeOutTickFFtoFC_Enable = 0;
dgiIsoTp.IsoTpFC = 0x0F & CanData[0];
dgiIsoTp.IsoTpBlocksize = CanData[1];
dgiIsoTp.IsoTpST = CanData[2];
dgiIsoTp.IsoTpCfFlag = TP_N_WAIT;
CF_Tick = dgiIsoTp.IsoTpST >> 0x01;
CF_TickEnable = 1;
}
}
break;
}
}

请你支持我,让我有个主意。在此处输入图像描述

@斯皮勒先生,非常感谢你的回复。正如你所解释的,我对我的代码进行了更改,我忘记更新第一个字节0x10 FF。从上面的CAPL代码中,我又添加了几行进行测试,部分代码正在运行。

最初,我的长度为17字节,用于写入2E F190。我正在向内存中写入7个字节。我想读我写在内存中的字节。但当我请求22 F190(我设置了最大长度17字节)时,我没有收到我写的所有7个字节。你能注意到错误在哪里吗?

on message 0x713
{
checkByte0 = this.byte(0) & 0x30;  
write("checkbyte value %x",checkByte0 );
if(checkByte0 == 0x30) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;    
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
else if(checkByte0 == 0x10) //FC frame
{    
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;    
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
}

//send request write data by identifier 2E F190 parameters
on key 'q'
{  
msg.byte(0) = 0x10;
msg.byte(1) = 0x0A;
msg.byte(2) = 0x2E;
msg.byte(3) = 0xF1;
msg.byte(4) = 0x90;
msg.byte(5) = 0x10;
msg.byte(6) = 0x20;
msg.byte(7) = 0x30;
output(msg);  
}

在陷阱中,你可以注意到我现在可以发送多帧代码了。如果在此处输入图像描述

您想要发送有效载荷

2E F1 90 10 20 30 40 50 60 70

使用ISO TP。

为此,您必须遵循ISO-TP规范,并将数据分割为一个第一帧和(可能是几个)

连续帧这些帧应该看起来像:

第一帧:10 0A 2E F1 90 10 20 30

连续帧:21 40 50 60 70 00 00 00

说明:

10 0A 2E F1 90 10 20 30:

  • 1在第一个半字节中意味着,这是第一个帧
  • CCD_ 15接下来的三个半字节包含有效载荷的长度。您想要发送10个字节,因此0x00A个字节

之后,第一帧包含有效负载的前6个字节。

21 40 50 60 70 00 00 00:

  • 2在第一个半字节中意味着,这是一个连续帧
  • 第二个半字节中的1意味着,这是第一个连续帧,第二个将具有2,依此类推

之后是接下来的7个字节的有效负载。

在CAPL代码中,这看起来像:

on key 'q'
{  
msg.byte(0) = 0x10;
msg.byte(1) = 0x0A
msg.byte(2) = 0x2E;
msg.byte(3) = 0xF1;
msg.byte(4) = 0x90;
msg.byte(5) = 0x10;
msg.byte(6) = 0x20;
msg.byte(7) = 0x30;
output(msg);  
}
on message 0x713
{
checkByte0 = this.byte(0) & 0x30;  
if(checkByte0 == 0x30) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;    
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
}

所以你要做的是:

发送第一帧,等待流量控制帧,发送连续帧。

同样,不需要手动执行此操作。CANoe附带了CanTp的实现。IIRC,CANoe提供了一个名为";CanTp";或";IsoTp";。没有必要使用客户尽职调查。

顺便说一下;客户端";以及";服务器";在ISOTP中。当您在服务器端有一个有效的实现时,您可以简单地在客户端使用相同的逻辑。

最新更新