繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM