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 100enables automatic recovery from bus-off conditionstxqueuelen 5000increases 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.