How to send diagnosis with Canoe CAPL


foreword

Taking UDS diagnosis as an example, GMLAN will have some differences, which are similar.
Generally, after the Canoe project loads CDD, you can directly click the required diagnosis command through the diagnosis interface of the Canoe project to send the diagnosis.
insert image description here
Then why do you need to send diagnostics through CAPL?
1. The data length of the diagnostic interface and some parameter ranges are limited (maximum and minimum values), but if you need to verify that the wrong length or parameter data that exceeds the range is sent There is no way to send through the diagnostic panel when the ECU's response meets the requirements.
2. Time, maybe you need two consecutive diagnostics sent in how long interval, manual click is too slow.
Or after your ECU fixes a certain bug and the software is upgraded, it is not enough to just test the bug you fixed. It is better to test all the diagnostics, one by one is too slow, and the script test is fast and accurate enough.


1. Directly call the diagnostic sending in CDD

In CAPL, diagnosis can also be understood as a special data type similar to int.
The keyword is diagRequest, provided that CDD is loaded in your Canoe project.
Edit diagRequest in CAPL, and then press the space, the compiler will automatically match the CDD name loaded in your canoe project.
insert image description here
After selecting the CDD name, press '.', the compiler will automatically match the list of diagnostics supported by this CDD, and then select the diagnostic you want to send.
insert image description here
Take the diagnosis request 10 03 to be sent to the extension layer as an example, give this diagnosis request a name Diag_Tx_10_03, and the data type of such a diagnosis request is defined.
insert image description here
After the definition is complete, the function to send the diagnostic request is diagSendRequest (diagRequest obj), and the parameters in the brackets are the diagnostic requests we defined.
That is:

on key 't'
{
  diagSendRequest(Diag_Tx_10_03);
}

Save, compile, and run the project, click the button t,
insert image description here
and other services are the same, such as the diagnosis of reading SN of the 0x22 service

diagRequest Door.SerialNumber_Read Diag_Tx_ReadSN;

on key 's'
{
  diagSendRequest(Diag_Tx_ReadSN);
}

insert image description here

Careful students may ask why Trace is both Tx and no Rx, because I don’t have a real ECU module at hand, I use a virtual ECU, and the response data is simulated by another node, but this does not affect us For test verification, if there is no real ECU, you need to set it as a simulated bus if you want to use verification.
insert image description here

2. Send diagnosis in the form of message

Call the diagnosis in CDD to send, and finally reflected in the data stream, it is still sent in the form of a message, so the diagnosis can also be sent in the form of a message, but if the request ID of the defined message is a request for diagnosis id, and the first 2 bytes in the diagnosis determine whether it is a single frame or multiple frames.
If it is a single frame, the first byte in the diagnosis represents the subsequent effective byte length.
If it is a multi-frame, the lower 4 bits of the first byte and the upper 8 bits of the second byte in the diagnosis represent the effective byte length

For example, when sending a request to enter the extension layer, the sent message data is 02 10 03, where 02 means that only 2 bytes are valid data bits (10 03).

If you don’t know how to use Canoe to send messages, you can refer to this
link: CAPL sends messages .

picture:

message 0x700 Diag_Tx_Request;

on key 't'
{
  Diag_Tx_Request.dlc=8;
  Diag_Tx_Request.byte(0)=0x02;
  Diag_Tx_Request.byte(1)=0x10;
  Diag_Tx_Request.byte(2)=0x03;
  output(Diag_Tx_Request);
}

3. How to use CAPL to send multi-frame diagnosis

ECU diagnosis can only send up to 8bytes of data per frame (CAN FD seems to be 64bytes), but what to do if there is a diagnosis that needs to send more than 8bytes of data, it needs to send multiple frames of data to complete a transmission, and more The transmission of frame data requires a response from the ECU, that is to say

My host computer first sends the first frame of data (first frame) to the ECU, and the
ECU needs to give a response (flow control frame) before
the host computer can then send subsequent data frames (continuous frames).
insert image description here
For example, I need to send 1, 2, 3, 4, 5, 6, 7, 8, 9, A total of 10 data, and only 8 data can be sent in one frame, which cannot be finished.
1. I need to send the first frame first, and the high 4 bits of the first byte are 1 to represent the first frame. After receiving this, the ECU will know that you need more than one frame, and then send the flow control frame to you. Let you have the opportunity to send it down.
The first frame is as follows:

0x10 0x0A 0x01 0x02 0x03 0x04 0x05 0x06
where 1 in 0x10 represents the first frame, 00A represents the effective data length, 1, 2, 3, 4, 5, 6 are the data to be sent.

2. The ECU replies with a flow control frame, the first byte of which is 0x30. After the host computer receives this flow control frame, it will continue to send the data that has not been sent just now.
0x30 0x00 0x00 0x00 0x00 x00 0x00 0x00

3. The upper computer then sends subsequent data frames (continuous frames). The upper 4 bits of the first byte of the continuous frame are 2. After the ECU receives 2, it knows that this data is connected with the previous frame.
0x21 0x07 0x08 0x09 0x0A
insert image description here

3.1 After monitoring the flow control frame, send the multi-frame data by itself

Suppose we send F189 in the diagnosis by sending a message, the data to be written is 13 bytes, plus 0x2E 0xF1 0x89, it is 16 bits, one frame cannot be sent, and multiple frames are required.
Step 1: Send the first frame to the ECU
Step 2: Wait for the flow control frame to receive the response from the ECU
Step 3: Send continuous frames to the ECU

The length in the first frame occupies 2 bytes (the upper 4 bits of byte1 represent the frame type, the lower 4 bits of byte1 and the 8 bits of byte2 together define the effective data length)

insert image description here
The first frame should be sent like this, the first 0x10, the upper four bits are 1 means it is the first frame, the second byte 0x10 means the subsequent effective data length is 16 bits.
0x10 0x10 0x2E 0xF1 0x89 0x00 0x00 0x00

After sending, it is necessary to wait for the ECU to respond (reply flow control frame 0x30) before sending subsequent data frames (continuous frames).

on key 't'
{
  Diag_Tx_Request.dlc=8;
  Diag_Tx_Request.byte(0)=0x10;
  Diag_Tx_Request.byte(1)=0x10;
  Diag_Tx_Request.byte(2)=0x2E;
  Diag_Tx_Request.byte(3)=0xF1;
  Diag_Tx_Request.byte(4)=0x89;
  Diag_Tx_Request.byte(5)=0x00;
  Diag_Tx_Request.byte(6)=0x00;
  Diag_Tx_Request.byte(7)=0x00;
  output(Diag_Tx_Request);//先发首帧
  Flag_Multi_F189=1;
}

//0x600是ECU的响应ID,就是说接收到ID为0x600的报文以后就会触发下面这个函数
on message 0x600
{
  if(this.byte(0)==0x30)//看看第一个byte如果是0x30代表是流控帧,代表可以接着往下发送数据
  {
    if(Flag_Multi_F189)//判断是不是F189的流控帧
    {
      Flag_Multi_F189=0;
      Diag_Tx_Request.byte(0)=0x21;
      Diag_Tx_Request.byte(1)=0x00;
      Diag_Tx_Request.byte(2)=0x00;
      Diag_Tx_Request.byte(3)=0x00;
      Diag_Tx_Request.byte(4)=0x00;
      Diag_Tx_Request.byte(5)=0x00;
      Diag_Tx_Request.byte(6)=0x00;
      Diag_Tx_Request.byte(7)=0x00;
      output(Diag_Tx_Request);//连续帧一次发不完可以一直连续发
      
      Diag_Tx_Request.byte(0)=0x22;
      Diag_Tx_Request.byte(1)=0x00;
      Diag_Tx_Request.byte(2)=0x00;
      Diag_Tx_Request.byte(3)=0x00;
      output(Diag_Tx_Request);//连续帧一次发不完可以一直连续发,两个连续帧之间是否需要时间间隔是看流控帧返回的数据决定的,这里不展开讲了,有需要的可以留言,可以专门写一篇各个时间参数的
    }
  }
}
  

insert image description here
This is a multi-frame transmission that sends 16 data and can be written like this.
If you want to send 1000 bytes, you can also write it like this, but it will be more troublesome.

3.2 Call the diagnostic send in CDD

Still take sending diagnosis F189 as an example, you can refer to the above introduction to call the diagnosis in CDD to send, but the sent data is the default data of the diagnosis interface, as follows, all 0.
insert image description here
If you want to modify the written data, you need to call the function

long diagSetParameterRaw (diagRequest obj, char parameterName[], byte* buffer, DWORD buffersize)

![Insert picture description here](https://img-blog.csdnimg.cn/bea9acad12b9495f8b7780868d852622.png
The description of each parameter is as follows

insert image description here
The first parameter obj is the variable defined with diagrequest earlier, which means which diagnostic request you want to send. The
second parameter is the modifier qualifier of the parameter you want to write. Where can I find this modifier? I understand. It is the most accurate to find it in the CDD file. For example, the parameter modifier of F189 is Part_Number. (Generally, Candelastudio is installed by default after Canoe is installed. You can directly double-click the CDD file to view the CDD. If you edit the CDD, you need a hardware license, but you don’t need a license to view it.) The third parameter is the data you want to write
insert image description here
. Into a buffer
The fourth parameter is the length of the buffer.

As follows, first define the diagrequest variable and the data buffer to be written, then assign values ​​to the written diagnostic parameters, and then send the diagnostic

byte ID_Write[13];
diagRequest Door.EcuIdentification_Write Diag_Tx_WriteID;

on key 'm'
{
  ID_Write[0]=0xff;
  ID_Write[1]=0x55;
  ID_Write[2]=0xAA;
  diagSetParameterRaw(Diag_Tx_WriteID,"Part_Number",ID_Write,13);
  diagSendRequest(Diag_Tx_WriteID);
}

insert image description here

3.3 Use CanTp to send packets and frames

When you use the first message method to send multi-frame diagnostics, have you ever thought that if there is a function, I will directly tell how long the data is to be sent, and then give the data to him, and let it send it by itself, so that I don't need to subcontract the data myself.

Yes, cantp, I understand that its function is to package/subpackage these data according to the protocol.

However, it is not a built-in function of CAPL, and an additional library needs to be loaded, but this library is available when installing canoe.
3.1: Copy the dll file in the installation directory to your project directory.
insert image description here
3.2: In the configuration option of the node, select Components, and then select Add to add the osek_dp.dll file
insert image description here
3.3 Select to add the osek_tp.dll file in CAPL, save, where ".\osek_tp.dll" is a relative path, where .\ is Represents your project file path. My dll file is directly placed in the project directory.
insert image description here
insert image description here
3.4. After clicking to save the CAPL file, you will find that there is more osek_tp.dll on the right side of the CAPL editor. After clicking + to expand, you will see The functions supported in this dll library open up a lot of function interfaces for you. After the includes, you can use these functions, just like the functions that come with the editor.
insert image description here
3.5 How to use the functions in this library? There are many functions, most of which I don’t understand what they mean,
but it is enough to know a few functions that can send messages, and you can try others by yourself.
To use cantp to send functions, there are several steps.
The first step: connect first.
The function used is CanTpCreateConnection(). I understand that the function of this step is to first determine whether it is a standard frame or an extended frame.
insert image description here
Step 2: Set the ID
Set the ID of the sending request and the ID of the ECU response.
insert image description here
The third step is to send data
insert image description here
. A connhandle will be used in these steps, which is a piece of data returned when the connection is established in the first step, that is, no matter what you do It must be based on the connection ok. .
The first parameter is the handle, which is obtained after the connection is established, and
the second parameter is the data you want to send
The third data is the length of the data you want to send

Let's still take sending diagnostic F189 as an example
insert image description here

code show as below

includes
{
   #pragma library (".\osek_tp.dll")
}

variables
{
    const dword Diag_Tx_id = 0x700;
    const dword Diag_Rx_id = 0x600;
    const byte  TpPadding =  0x55;

    byte ID_Write[16];
    long TpHandle;
}
on start
{
    TpHandle = CanTpCreateConnection(0); //连接,参数是0代表标准帧
    CanTpSetTxIdentifier(TpHandle, Diag_Tx_id); //设置ID
    CanTpSetRxIdentifier(TpHandle, Diag_Rx_id);  
    CanTpSetPadding(TpHandle, TpPadding);//设置填充位
}

on key 't'
{
 ID_Write[0]=0x2E;
 ID_Write[1]=0xF1; 
 ID_Write[2]=0x89;
 ID_Write[3]=0x33; //想用发送什么数据,给要发送的数组赋值就好了,我这里随便举例一个数据
 CanTpSendData(TpHandle, ID_Write, 16);//发送
}

It only needs to be done once to establish a connection and set the id, so just put it in on start and set it once when the project is running.
There is also a function CanTpSetPadding.
This function means,
for example, when you send a frame of data, 02 10 03 only has 3 bytes, but when you need to send 8 bytes in a frame (some car manufacturers have such requirements ), the last 5 bytes are actually meaningless and can be filled casually, but some car manufacturers will require padding with 0xAA or 0x55... The
function CanTpSetPadding is to set the padding data. If the car factory does not require it, you can not use this.

Look at the data below, fill the bits of 0x55, that is, the valid data in the last continuous frame is not enough for 8 bits, and it needs to be filled.insert image description here

Guess you like

Origin blog.csdn.net/glenwan/article/details/123584394