0

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

  • Could you elaborate what _this issue_ is? With which CAN ID do you receive messages from the server? `0x71B` or `0x713`? Why are you using a manual implementation of ISO-TP? CANoe offers an implementation of ISO-TP (CAN-TP) which can be used in CAPL. Why are you doing diagnostics by hand? In case you do not have a CDD, you could use basic diagnostics. – MSpiller Oct 06 '22 at 15:38
  • Hi M. Spiller, thank you responding quickly. I receive CAN ID 0x713 from client(Tester box) to server (ECU) I am working on server. In server side (ECU) I have already implemented ISOTP protocol which works (i.e., server to client flow control is working perfectly). Yes, currently I am going with manual implementation. The reason I don't have CDD file and license to candela. Currently, for testing purpose I have to follow manual method where I could implement a CAPL code to send message request to server using SID 2E. Please could you help me? – Mahesh Reddy Oct 07 '22 at 07:22
  • I want to know how to send request message with more than 8 byte data while calling SID 2E writedatabyidentifier. e.g Rq: CAN ID 0x713 10 2E F1 90 10 20 30 40 50 60 70 Respons: CAN ID 0x71B 03 6E F1 90. My problem lie with request message how to define the logic in CAPL ? – Mahesh Reddy Oct 07 '22 at 07:44

1 Answers1

0

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.

MSpiller
  • 3,500
  • 2
  • 12
  • 24
  • thank you for qucik response. I have added few points to my question. Please could you check and provide me a solution for my question. – Mahesh Reddy Oct 07 '22 at 10:27
  • @MaheshReddy Not sure, what you mean. In the screenshot you have attached, I cannot find any message, that corresponds to the code of my answer. I assume you want to access service `2E F1 90`, that message should start (because it is a first frame) with `1` as the first nibble. In your screenshot it starts with `09`, which would mean a single frame with 9 bytes, which is illegal. – MSpiller Oct 07 '22 at 11:53
  • I notice the mistake and I update the first byte as you explained and it works fine. But I see issue that I am not able to write all bytes to memory. As you can see in the picture Read SID 22 F190 request and response. I am checking code from my end. I assume since FC is not transmitted could be the issue ? Just correct me with an exampe would be really helpful. – Mahesh Reddy Oct 07 '22 at 13:10
  • I've noticed when debugging the CAPL program requesting next CF consecutive frame with value 20 as byte(0). This throwing error because I have not defined the condition to receive value 0x20. Is there a way to avoid this issue with in CAPL ? – Mahesh Reddy Oct 07 '22 at 14:44
  • @MaheshReddy I cannot really follow. I'd suggest to create a new question focussed on your problem. After your edits to the question and attaching the same screenshot twice, I don't think anyone could help you here. – MSpiller Oct 10 '22 at 08:09