Home:ALL Converter>CAPL multi frame handling for CAN request message 2E SID

CAPL multi frame handling for CAN request message 2E SID

Ask Time:2022-10-06T23:11:51         Author:Mahesh Reddy

Json Formatter

I am trying to find an answer where I could able to read the flow control for request message using CAPL program for SID 2E UDS Diagnostic. I have implemented ISOTP protocol on server side for transmitting multi frame response message which is working fine.

I have added below CAPL program for your reference. Now my problem is I want to write a CAPL program which works like a client request message. I have added few keys to trigger the request msg. As I am not able to receive flow control FC and CF consecutive frame while requesting the message. I don't have a CDD file to config in the diganostics panel.

Please could someone help me to fix this issue. At least an example would be really appreciated.

/*@!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);
//  }
}

You want to send the payload

2E F1 90 10 20 30 40 50 60 70

using ISO TP.

In order to do so, you have to follow the ISO-TP specification and segment the data into one first frame and (possibly several) consecutive frames. The consecutive frames should only be sent after you have received a flow control frame.

These frames should look like:

First frame: 10 0A 2E F1 90 10 20 30

Consecutive frame: 21 40 50 60 70 00 00 00

Explanation:

10 0A 2E F1 90 10 20 30:

  • 1 in the first nibble means, this is a first frame
  • 0 0A the next three nibbles contain the length of the payload. You want to send 10 bytes, hence 0x00A bytes

After that the first frame contains the first 6 bytes of your payload.

21 40 50 60 70 00 00 00:

  • 2 in the first nibble means, this is a consecutive frame
  • 1 in the second nibble means, that this is the first consecutive frame, the second would have a 2 here and so on.

After that there are the next 7 bytes of your payload.

In CAPL code this would look like:

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);
  }
}

So what you have to do is:

Send the first frame, wait for the flow control frame, send the consecutive frame.

Again, there is no need to do this manually. CANoe comes with an implementation of CanTp. IIRC, there is a demo configuration coming with CANoe called "CanTp" or "IsoTp". There is no need to use a CDD.

By the way, there is no difference between "client" and "server" in ISOTP. When you have a working implementation on server side, you can simply use the same logic on client side.

@M.Spiller, thank you for explaining in detail. I have tried as you explained but I am confused when receiving the bytes from CAN request followed by capl code. Below I am adding code where I receive the request from CANOe. I want to know, do I missed something that I need to add a code to server to read request from CANOe. Currently, CANOe is not sending multiframe since it is looking response message from server (FC) I assume. Please could tell me where could be the issue ?

/* 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;
            }
          }

Please need your support me to get an idea. enter image description here

@M.Spiller, thank you so much for responding. I made changes in my code as you explained I forgot to update the 1st byte 0x10 FF. . From the above CAPL code I have added few more line to test and partially it is working.

Initially I have length 17 bytes for write 2E F190. I am writing 7 bytes into memory. I want to read bytes which I have written in memory. But when I request 22 F190 (I have set max length 17 bytes) where I get don'T receive all the7 bytes which I have written. Please could you notice where the mistake would be ?

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);  
}

In the pitcure you can notice I am able to send multi frame the code is able to receive now.Please let me know if enter image description here

Author:Mahesh Reddy,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/73976155/capl-multi-frame-handling-for-can-request-message-2e-sid
yy