Skip to main content

Linux CAN Bus Setup and systemd Services (Debian-Based)

This document describes how to:

  • Prepare a Debian-based Linux system for CAN bus usage
  • Install required tooling
  • Bring up CAN interfaces using per-interface systemd services
  • Operate CAN interfaces via SocketCAN

It applies to any Linux system where the kernel exposes CAN devices as canX.


Prerequisites​

  • Debian or Debian-based distribution (Debian, Ubuntu, Raspberry Pi OS, etc.)
  • Linux kernel with SocketCAN support
  • Supported CAN hardware (SPI, USB, PCIe, SoC-integrated)

If Linux exposes can0, MapsMessaging can read it.


Verify Kernel CAN Support​

Most modern Debian kernels include CAN support.

Check loaded modules:

lsmod | grep can

Typical modules include:

  • can
  • can_raw
  • can_dev
  • Hardware-specific drivers (e.g. mcp251x, peak_usb)

If required, load core modules manually:

sudo modprobe can
sudo modprobe can_raw
sudo modprobe can_dev

Install Required Packages​

Install SocketCAN utilities:

sudo apt update
sudo apt install can-utils

These tools are required for:

  • Interface testing
  • Frame inspection
  • Diagnostics

Manual Interface Bring-up (Validation Step)​

Before creating systemd services, verify the interface works manually.

Example using 250 kbit/s:

sudo ip link set can0 down
sudo ip link set can0 up type can bitrate 250000 restart-ms 100
sudo ip link set can0 txqueuelen 5000

Verify:

ip -details link show can0

If this fails, fix hardware or driver issues before continuing.


systemd Services (Per Interface)​

Each CAN interface should be managed by its own unit file. This allows independent configuration, startup, and debugging.


can0.service​

Create:

/etc/systemd/system/can0.service

[Unit]
Description=Bring up CAN interface can0
After=network.target
Requires=network.target

[Service]
Type=oneshot
RemainAfterExit=yes

ExecStart=/sbin/ip link set can0 down
ExecStart=/sbin/ip link set can0 up type can bitrate 250000 restart-ms 100
ExecStart=/sbin/ip link set can0 txqueuelen 5000

ExecStop=/sbin/ip link set can0 down

[Install]
WantedBy=multi-user.target

can1.service​

Create only if a second interface exists.

/etc/systemd/system/can1.service

[Unit]
Description=Bring up CAN interface can1
After=network.target
Requires=network.target

[Service]
Type=oneshot
RemainAfterExit=yes

ExecStart=/sbin/ip link set can1 down
ExecStart=/sbin/ip link set can1 up type can bitrate 250000 restart-ms 100
ExecStart=/sbin/ip link set can1 txqueuelen 5000

ExecStop=/sbin/ip link set can1 down

[Install]
WantedBy=multi-user.target

Enable and Start Services​

Reload systemd:

sudo systemctl daemon-reload

Enable required interfaces:

sudo systemctl enable can0.service
sudo systemctl enable can1.service

Start services:

sudo systemctl start can0.service
sudo systemctl start can1.service

Verification​

Check service status:

systemctl status can0.service
systemctl status can1.service

Verify interface state:

ip -details link show can0
ip -details link show can1

Basic CAN Bus Test​

Dump frames:

candump can0

Send a test frame:

cansend can0 123#DEADBEEF

Loopback Test (No External Hardware)​

sudo ip link set can0 down
sudo ip link set can0 up type can bitrate 250000 loopback on

Operational Notes​

  • restart-ms 100 enables automatic recovery from bus-off conditions
  • txqueuelen 5000 increases kernel-side buffering only
  • Bitrate must match all devices on the bus
  • Do not enable services for interfaces that do not exist

Summary​

This setup provides:

  • Deterministic interface startup
  • Clean recovery from bus errors
  • Independent control of each CAN interface
  • Compatibility with all SocketCAN-based software

Hardware sets the limits. Linux exposes the interface. MapsMessaging reads the frames.