🍗 Wiki

CAN

Controller Area Network Protocol

CAN: Controller Area Network Protocol

A bus protocol used in many hardwares, allows microcontrollers to communicate with the others, frequently used in automobiles.

1. History

Before the CAN bus there was the UART protocol. But Mercedes-Benz wanted to make more modules and control chips to be communicated, because the UART only supports point-to-point communication.

Mercedes-Benz requested Bosch to make such protocol, that was the first release of the CAN protocol.

1.1. CAN 2.0 A/B

CAN 2.0 Specification Part A is for the standard format with an 11-bit identifier, and part B is for the extended format with a 29-bit identifier.

1.2. CAN-FD

FD is a short of 'Flexible Data'. As the name says, the CAN-FD is an extended protocol but supports flxeible data communication. With CAN FD, the ECUs can communicate with lower latency and higher bandwith compared with classical CAN.[3]

1.3. CAN-TP

Classic CAN protocol can only carry 8 bytes of data. If we have to deal with the other protocols over CAN, a frame can carry less than 8 bytes; UDS, for example, have to have SID and optional subfunction number, that would be 1~2 byes.

In order to transmit or receive more than 8 bytes, tehre is the CAN-TP.

1.3.1. VERY REALISTIC EXAMPLE

This is captured UDS on CAN data, for example.

CANID | DLC | Data
0x7e0 | 0x8 | 02 10 03
0x7e8 | 0x8 | 06 50 03 00 ca fe aa aa
...
0x7e0 | 0x8 | 03 22 f1 90
0x7e8 | 0x8 | 10 15 62 f1 90 54 48 49
0x7e0 | 0x8 | 30 00 00 00 00 00 00 00
0x7e8 | 0x8 | 21 53 20 49 53 20 41 4e
0x7e8 | 0x8 | 22 20 45 58 41 4d 50 4c
0x7e8 | 0x8 | 23 45 aa aa aa aa aa aa

Let’s dissect the data line by line. The data shown below is all the Single Frames.

In each line, CAN ID 0x7e0 is transmitting data (Tx), which is what you send. And CAN ID 0x7e8 is receiving data (Rx), which is what your machine transmitted.

0x7e0 | 0x8 | 02 10 03
              ^^
              ||
              |`-- Data Length(2)
              `--- Single Frame(0)

0x7e8 | 0x8 | 06 50 03 00 ca fe aa aa
              ^^
              ||
              |`-- Data Length(6)
              `--- Single Frame(0)

0x7e0 | 0x8 | 03 22 f1 90
              ^^
              ||
              |`-- Data Length(3)
              `--- Single Frame(0)

An example below presents receiveing 0x15(21) bytes of data.

0x7e8 | 0x8 | 10 15 62 f1 90 54 48 49
              |^ ^^
              || ||
              |`-``--- Data Length(0x015)
              `------- First Frame(1)

0x7e8 | 0x8 | 21 53 20 49 53 20 41 4e
              ||
              |`--- Consecutive Frame(2)
              `---- 1st (1)

0x7e8 | 0x8 | 22 20 45 58 41 4d 50 4c
              ||
              |`--- Consecutive Frame(2)
              `---- 2nd (2)

0x7e8 | 0x8 | 23 45 aa aa aa aa aa aa
              ||
              |`--- Consecutive Frame(2)
              `---- 3rd (3)

…​And it is possible to control the flow by Flow Control Frame.

0x7e0 | 0x8 | 30 00 00 00 00 00 00 00
              |
              `---- Flow Control Frame (3)

1.4. CAN DBC

DBC file is a predefined information file about how to make signals and commuincations. So it is a specification or draft of ECUs basically, it could be a single .txt file or README.md and so on, but there is a .dbc widely used in industry, de-facto standardized by Vector.

The company Vector Informatik provides the tool for .dbc file, CANdb++.

2. Useful Tools & Libraries

Since it has long history, there are several way to analyze CAN signals.

2.1. can-utils

A part of linux-can project, provides some useful tools like candump, cansend, and cansniffer.

In Ubuntu 22.04, there is the can-utils package in apt.

sudo apt install can-utils

2.3. python-can

2.3.1. Examples

import can

bus = can.interface.Bus(bustype='kvaser', channel = 0, bitrate = 500000)

while True:
    print(bus.recv())

It is recommended to use with statement if you created a Bus instance.

# import the library
import can

# create a bus instance using 'with' statement,
# this will cause bus.shutdown() to be called on the block exit;
# many other interfaces are supported as well (see documentation)
with can.Bus(interface='socketcan',
              channel='vcan0',
              receive_own_messages=True) as bus:

   # send a message
   message = can.Message(arbitration_id=123, is_extended_id=True,
                         data=[0x11, 0x22, 0x33])
   bus.send(message, timeout=0.2)

   # iterate over received messages
   for msg in bus:
       print(f"{msg.arbitration_id:X}: {msg.data}")

   # or use an asynchronous notifier
   notifier = can.Notifier(bus, [can.Logger("recorded.log"), can.Printer()])

2.4. python-can-isotp

A developer of CanTools also made this.

2.5. CANdb++

A proprietary tool provided by Vector Informatik to visualize and analyze .dbc files.

2.6. CANdevStudio

CANdevStudio aims to be cost-effective replacement for CAN simulation software. [4]

2.7. Arduino-CAN

If you want/have to deal CAN with Arduino, there is a CAN library for Arduino.

2.8. CANToolz

Black-box CAN network analysis framework

Maybe discontinued.

3. Reference

4. See Also


1. Kent from Kvaser says there are some reasons to switch from Classical CAN to CAN FD. https://www.kvaser.com/wp-content/uploads/2016/10/comparing-can-fd-with-classical-can.pdf
2. An introduction video on YouTube
3. Kent from Kvaser says there are some reasons to switch from Classical CAN to CAN FD. https://www.kvaser.com/wp-content/uploads/2016/10/comparing-can-fd-with-classical-can.pdf
4. An introduction video on YouTube