Skip to content

Using CAN

The Linux kernel provides CAN interoperability out-of-the-box with the SocketCAN subsystem. SocketCAN exposes CAN device drivers as network interfaces, thus CAN sockets can be interacted with similar methods to TCP/IP.

Physical CAN

The following steps can be used to bring up a CAN interface:

  1. Load the required SocketCAN kernel modules. (This step may be unnecessary if the drivers are initialized when the kernel was compiled). Verify the module is loaded with lsmod | grep can or with dmesg | grep can.
    sh
    modprobe can
    modprobe can_raw
    lsmod | grep can
    modprobe can
    modprobe can_raw
    lsmod | grep can

2. Establish the network interface.
	```sh
	sudo ip link set can0 type can bitrate 125000 restart-ms 100

2. Establish the network interface.
	```sh
	sudo ip link set can0 type can bitrate 125000 restart-ms 100
  1. Initialize the network interface. Verify the network is UP with ip a | grep can0
    sh
    sudo ip link set up can0
    ip a | grep can0
    sudo ip link set up can0
    ip a | grep can0

Enabling on Boot

To enable the CAN interface on boot for Ubuntu 20.04+ you can use systemd-networkd.

  1. Add the following contents to the file /etc/systemd/network/80-can.network
ini
[Match]
Name=can0

[CAN]
BitRate=125K
RestartSec=100ms
[Match]
Name=can0

[CAN]
BitRate=125K
RestartSec=100ms
  1. Enable and start systemd-networkd
sh
systemctl start systemd-networkd
systemctl enable systemd-networkd
systemctl start systemd-networkd
systemctl enable systemd-networkd

[! Note] If you cannot load the SocketCAN modules with modprobe then it's possible that your kernel wasn't compiled with CAN driver support. You will either have to use a virtual CAN interface or recompile your kernel with CAN drivers enabled.

Virtual CAN

The steps to enable a virtual CAN interface are nearly identical.

  1. Load the vcan kernel driver.
sh
sudo modprobe vcan
sudo modprobe vcan
  1. Establish the network interface. Optionally use the dev vcan0 to name your interface whatever you prefer.
sh
sudo ip link add dev vcan0 type vcan
sudo ip link add dev vcan0 type vcan
  1. Initialize the network interface.
    sh

sudo ip link set up vcan0


## Communcating with CAN Devices

CLI interaction with CAN devices is provided by the **can-utils** package.

```sh
sudo apt install can-utils
```

In the following commands the **can0** interface will be used, but virtual interfaces, e.g., **vcan0** can also be used.

Show all CAN messages via Stdout. The interface `can0` should be the name of your network interface. Use the the `-l` flag to record to a file; this will create a log with a name like **candump-2023-01-28_123456.log**.

```
candump can0
candump -l can0
```

Send a message on the `can0` interface.

```
cansend can0 123#00112233AA
```

Send random CAN data

```
cangen can0 -v
```

Print log files in ASCII

```
log2asc -I candump-2022-01-02_123456.log vcan0
```

Replay a recorded CAN dump

```
canplayer -I candump-2012-01-02_123456.log
```

It is recommended to use WireShark to analyze/sniff CAN frames (see [[Using Wireshark]]).

**ADDITIONAL RESOURCES**

- https://www.pragmaticlinux.com/2021/07/automatically-bring-up-a-socketcan-interface-on-boot/
- https://www.pragmaticlinux.com/2021/10/how-to-create-a-virtual-can-interface-on-linux/
- https://elinux.org/Bringing_CAN_interface_up
- http://www.armadeus.org/wiki/index.php?title=CAN_bus_Linux_driver
- https://manpages.ubuntu.com/manpages/bionic/man1/canplayer.1.html
- https://sgframework.readthedocs.io/en/latest/cantutorial.html
  QEMU with CAN Emulation
- https://www.qemu.org/docs/master/system/devices/can.html
- https://devel.rtems.org/wiki/Developer/Simulators/QEMU/CANEmulation#AddSocketCANdevice

## Communcating with CAN Devices

CLI interaction with CAN devices is provided by the **can-utils** package.

```sh
sudo apt install can-utils
```

In the following commands the **can0** interface will be used, but virtual interfaces, e.g., **vcan0** can also be used.

Show all CAN messages via Stdout. The interface `can0` should be the name of your network interface. Use the the `-l` flag to record to a file; this will create a log with a name like **candump-2023-01-28_123456.log**.

```
candump can0
candump -l can0
```

Send a message on the `can0` interface.

```
cansend can0 123#00112233AA
```

Send random CAN data

```
cangen can0 -v
```

Print log files in ASCII

```
log2asc -I candump-2022-01-02_123456.log vcan0
```

Replay a recorded CAN dump

```
canplayer -I candump-2012-01-02_123456.log
```

It is recommended to use WireShark to analyze/sniff CAN frames (see [[Using Wireshark]]).

**ADDITIONAL RESOURCES**

- https://www.pragmaticlinux.com/2021/07/automatically-bring-up-a-socketcan-interface-on-boot/
- https://www.pragmaticlinux.com/2021/10/how-to-create-a-virtual-can-interface-on-linux/
- https://elinux.org/Bringing_CAN_interface_up
- http://www.armadeus.org/wiki/index.php?title=CAN_bus_Linux_driver
- https://manpages.ubuntu.com/manpages/bionic/man1/canplayer.1.html
- https://sgframework.readthedocs.io/en/latest/cantutorial.html
  QEMU with CAN Emulation
- https://www.qemu.org/docs/master/system/devices/can.html
- https://devel.rtems.org/wiki/Developer/Simulators/QEMU/CANEmulation#AddSocketCANdevice