[英]CAPL multi frame handling for CAN request message 2E SID
我试图找到一个答案,我可以使用 SID 2E UDS 诊断的 CAPL 程序读取请求消息的流控制。 我在服务器端实现了 ISOTP 协议,用于传输工作正常的多帧响应消息。
我在下面添加了 CAPL 程序供您参考。 现在我的问题是我想编写一个像客户端请求消息一样工作的 CAPL 程序。 我添加了几个键来触发请求消息。 因为我在请求消息时无法接收流控制 FC 和 CF 连续帧。 我没有要在诊断面板中配置的 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
表示这是第一帧0 0A
接下来的三个半字节包含有效载荷的长度。 你想发送 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”的演示配置。 无需使用 CDD。
顺便说一下,在 ISOTP 中“客户端”和“服务器”之间没有区别。 当你在服务器端有一个有效的实现时,你可以简单地在客户端使用相同的逻辑。
@M.Spiller,感谢您详细解释。 我已经按照您的解释进行了尝试,但是当我从 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;
}
}
请需要你的支持我得到一个想法。 在此处输入图像描述
@M.Spiller,非常感谢您的回复。 正如您解释的那样,我对代码进行了更改我忘记更新第一个字节 0x10 FF。 . 从上面的 CAPL 代码中,我又添加了几行代码进行测试,部分代码可以正常工作。
最初我有 17 个字节的长度用于写入 2E F190。 我正在将 7 个字节写入 memory。我想读取我在 memory 中写入的字节。但是当我请求 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
表示这是第一帧0 0A
接下来的三个半字节包含有效载荷的长度。 你想发送 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”的演示配置。 无需使用 CDD。
顺便说一下,在 ISOTP 中“客户端”和“服务器”之间没有区别。 当你在服务器端有一个有效的实现时,你可以简单地在客户端使用相同的逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.