Skip to content

Can bus on linux

CAN bus on Linux

Create virtual UDP can bus

This virutal bus works in a docker container without access to host system.

create using python-can

from can.interfaces.udp_multicast import UdpMulticastBus

bus = UdpMulticastBus("224.0.0.1", interface="udp_multicast")

Note

Using udp_multicast will always result in bus receiving own messages.

Create virtual system can bus

Note

This works only on linux systems with access to kernel. Does not work in a docker container.

This will create vcan0 adapter:

sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

Now install

sudo apt install can-utils

And test it, terminal 1:

candump vcan0

terminal 2:

cansend vcan0 123#DEADBEEF

Tip

You can install a system service to create virtual can on system startup. Use setup_vcan_service.sh for that.

Abstracting bus creation

get_can_bus() can help abstract away bus creation. Example code:

import os
import logging
from can.interfaces.udp_multicast import UdpMulticastBus
from can.interfaces.socketcan import SocketcanBus


def is_ci_environment() -> bool:
    """Check if the code is running in a CI environment"""
    return os.getenv("CI") == "true"


def get_can_bus() -> UdpMulticastBus | SocketcanBus:
    """Get a CAN bus instance, using environment variables
    CAN_CHANNEL and CAN_INTERFACE for configuration or a multicast bus in CI"""

    if is_ci_environment():
        return UdpMulticastBus("224.0.0.1", interface="udp_multicast")

    channel = os.getenv("CAN_CHANNEL")
    if channel is None:
        raise ValueError(
            "Missing CAN_CHANNEL environment variable, set to can0 or similar"
        )

    interface = os.getenv("CAN_INTERFACE", "socketcan")
    logging.info(f"Using CAN interface: {interface}, channel: {channel}")
    if interface == "udp_multicast":
        # note: will always receive own messages
        return UdpMulticastBus(channel, interface=interface)

    return SocketcanBus(
        channel=channel, interface=interface, receive_own_messages=False
    )

Setup can RPI hat

Tip

use setup_can.sh to install system service.