ISO 15765-2

So this blog can get a bit technical, so I apologize but I assure you this is some really fun stuff.

CAN BUS is intended for short, quick data transfer between controllers.  This is achieved by setting a limit of 8 Bytes maximum for any Frame that is sent on the bus.  Because of this limitation sending a message of more than 8 bytes needs to be broken up by the sending controller and reassembled by the receiving controller(s).  The ISO-15765-2 Transport Protocol is designed specifically for this.

Typically diagnostic messages also use this transport layer despite having more than 8 bytes or not.  ISO-15765-2 support Single-Frame transport as well.  In the case of diagnostic messages, the ISO TP is use simply to obscure the 8 byte limitation of CAN BUS.

ISO TP format…

Like all CAN messages, ISO TP messages must have an Arbitration ID.  This ID is not specified in the ISO TP specification and can be used for a number of things, but most of all, it is used to identify the message contents or destination controller.  For example a message with ArbID 0x7E0 might be intended for the Engine Controller from the Test Tool and messages with ArbID 0x7E8 might intended for the Test Tool from the Engine Controller.  These IDs are not part of the ISO TP portion of the specification but are required and serve the purpose of identifying the target controller for the message.

ISO TP contains PCI or Protocol Control Information bytes.  This data is there specifically to help the receiving controller know what type of Frame (Single, Multi, Flow Control, or Continue) is being transmitted, how many data bytes will be sent in the message, or if the receiver has somehow dropped a message.

Typically the PCI information is contained in the first byte of the each ISO frame.  This is referred to as the PCI byte.  This byte is broken into two pieces; the first four bits (or most significant bits) are the PCI Type.  There are four types:  First Frame (FF) = 1, Consecutive Frame (CF) = 2, Flow Control (FC) = 3, and Single (SF) = 0.

If your message is 7 bytes or smaller, it can fit into a single CAN Frame.  So this message’s first byte will contain a 0 in the first portion of the byte (i.e. 0x05 or 0x02).  The second part of the byte describes the message length; so if you have 4 bytes to transmit then the first byte will be 0x04.  The whole message may look like this: 0x04 0x01 0x02 0x03 0x04.  Any other bytes added to the remainder of the CAN frame can be disregarded, this is called Padding and in most cases is required (but not all) by receiving controllers.  The data is often set to 0x00, 0xFF or 0xAA.  An example of the same message before, but padded with 0xAA: 0x04 0x01 0x02 0x03 0x04 0xAA 0xAA 0xAA.  These two messages should be interpreted identically by the receiver as they should look at the 0x04 PCI byte and know that only four bytes were part of the message and the remaining data is padding.

If your message is 8 bytes or greater, then you will need to put your message in a Multi-Frame format.  There are three message types that make up a multi-frame message.

The first is the First Frame.  This is just as it sounds, the very first message you send of the multi-frame message.  This message is formatted with a 1 in the first portion of the PCI byte. (i.e. 0x10 or 0x14),  The next part of the byte is the first four most significant bits of the data length.  There are 12 bits total, so the next byte is the least significant byte of the data length.  For example if you want to send a message with 10 data bytes then the first TWO bytes are PCI bytes (unlike just one PCI byte in a single frame message).  This message’s PCI would be 0x10 0x0A.  Where 0x00A is the data length in hexadecimal (0x00A = 10 decimal).  So the first frame of a multi-frame message with 10 data bytes might look like this: 0x10 0x0A 0x01 0x02 0x03 0x04 0x05 0x06.  As a CAN frame cannot exceed 8 bytes, we cannot write any more data to our receiving controller so we must send the remaining bytes in a subsequent message.  But why send anymore data if the receiving controller is not available or busy?  This is why after we send a First Frame, we must wait for a Flow Control Frame from the controller we are send the data to.

Flow Control Frames are responses to First Frames with information on how and when to send subsequent frames.  Because not all controllers are created equal, a receiving controller may want to have the sender send ISO TP frames slowly or not at all.  This is done via the FC frame.  The FC frame has a 3 in the first portion of the PCI byte (i.e. 0x30 or 0x31).  Unlike previous frames, the FC frame is only PCI data; no user data is stored in this frame.  The second portion of the first byte is either a 0 or a 1. 0 means Clear To Send (CTS) and 1 means Wait. The Second Byte is the Block Size (BS).  This is used to tell the sender how many “Blocks” (Frames) it can send before it must wait for another FC frame.  This number can be between 0 and 255 where 0 means Do Not Wait (or send as many frames as are in the message without waiting).  The third and final byte in an FC frame is the Separation Time (ST).  The ST is there to tell the transmitter how long it must wait (in milliseconds) between frames.  This can be from 0-100 where 0 is Send As Fast As Possible.  101-255 are viable numbers, but they no longer are in ms but rather increment at higher numbers (you can take a look the specification for more info). A typical FC frame will look like this: 0x30 00 00 or 0x30 04 50 and may or may not contain Padding.

The last type of frame is the Consecutive Frame.  This is essentially the rest of the message.  The first part of the PCI byte is a 2.  The second part is a rolling counter starting at 1 and going to F then rolling over to 0.  This counter increments by 1 for each consecutive frame in the message.  It is not a frame counter as it does roll over (or back) to 0.  In the case of our previous example of a 10 byte message a CF would look like this: 0x21 0x07 0x08 0x09 0x0A (and may have padding at the end to fill the remaining bytes of the frame).

Here are some examples or Single and Multi-Frame messages:

Long Message without ISO TP:
0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 (total 24 bytes)

Multi-Frame Message with ISO TP (where {To and From ArbID} are the CAN Arbitration IDs not specified in the ISO specification):
{To ArbID} 0x10 0x18 0x01 0x02 0x03 0x04 0x05 0x06  – First Frame
{From ArbID} 0x30 0x00 0x00 – Flow Control Frame
{To ArbID} 0x21 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D – Consecutive Frame
{To ArbID} 0x22 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 – Consecutive Frame
{To ArbID} 0x23 0x15 0x16 0x17 0x18 0xAA 0xAA 0xAA – Consecutive Frame

Short Message without ISO TP:
0x01 0x02 0x03 0x04 0x05

Single Frame Message with ISO TP:
{To ArbID} 0x05 0x01 0x02 0x03 0x04 0x05 0xAA 0xAA  – Single Frame