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.