我正试图找到一个答案,在那里我可以使用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规范,并将数据分割为一个第一帧和(可能是几个) 连续帧这些帧应该看起来像: 第一帧: 连续帧: 说明: 之后,第一帧包含有效负载的前6个字节。 之后是接下来的7个字节的有效负载。 在CAPL代码中,这看起来像: 所以你要做的是: 发送第一帧,等待流量控制帧,发送连续帧。 同样,不需要手动执行此操作。CANoe附带了CanTp的实现。IIRC,CANoe提供了一个名为";CanTp";或";IsoTp";。没有必要使用客户尽职调查。 顺便说一下;客户端";以及";服务器";在ISOTP中。当您在服务器端有一个有效的实现时,您可以简单地在客户端使用相同的逻辑。 @斯皮勒先生,谢谢你的详细解释。正如你所解释的,我已经尝试过了,但当我收到CAN请求后面跟着capl代码的字节时,我感到困惑。下面我添加代码,我收到CANOe的请求。我想知道,我是否错过了一些需要添加代码到服务器以读取CANOe请求的东西。目前,CANOe并没有发送多帧,因为它正在寻找来自服务器(FC)的响应消息。请告诉我问题出在哪里? 请你支持我,让我有个主意。在此处输入图像描述 @斯皮勒先生,非常感谢你的回复。正如你所解释的,我对我的代码进行了更改,我忘记更新第一个字节0x10 FF。从上面的CAPL代码中,我又添加了几行进行测试,部分代码正在运行。 最初,我的长度为17字节,用于写入2E F190。我正在向内存中写入7个字节。我想读我写在内存中的字节。但当我请求22 F190(我设置了最大长度17字节)时,我没有收到我写的所有7个字节。你能注意到错误在哪里吗? 在陷阱中,你可以注意到我现在可以发送多帧代码了。如果在此处输入图像描述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
在第一个半字节中意味着,这是第一个帧0x00A
个字节21 40 50 60 70 00 00 00
:2
在第一个半字节中意味着,这是一个连续帧1
意味着,这是第一个连续帧,第二个将具有2
,依此类推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);
}
}
/* 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;
}
}
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规范,并将数据分割为一个第一帧和(可能是几个) 连续帧这些帧应该看起来像: 第一帧: 连续帧: 说明: 之后,第一帧包含有效负载的前6个字节。 之后是接下来的7个字节的有效负载。 在CAPL代码中,这看起来像: 所以你要做的是: 发送第一帧,等待流量控制帧,发送连续帧。 同样,不需要手动执行此操作。CANoe附带了CanTp的实现。IIRC,CANoe提供了一个名为";CanTp";或";IsoTp";。没有必要使用客户尽职调查。 顺便说一下;客户端";以及";服务器";在ISOTP中。当您在服务器端有一个有效的实现时,您可以简单地在客户端使用相同的逻辑。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
在第一个半字节中意味着,这是第一个帧0x00A
个字节21 40 50 60 70 00 00 00
:2
在第一个半字节中意味着,这是一个连续帧1
意味着,这是第一个连续帧,第二个将具有2
,依此类推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);
}
}