Skip to main content
Version: Torizon OS 7.x.y

How to Use CAN on Torizon OS

Introduction

In this article, we will show how to setup one or more CAN networks to be accessed in a containerized application in Torizon OS.

This article complies with the Typographic Conventions for Torizon Documentation

Prerequisites

CAN Support on Torizon

The following Kernel modules are ready to use:

  • can: CAN protocol module.
  • can-dev: Standard library for CAN drivers.
  • can-raw: Offers access to the CAN bus via the BSD socket API.
  • can-bcm: Broadcast Manager module, offers content filtering, timeout monitoring, sending of RTR frames, and cyclic CAN messages without permanent user interaction.
  • can-j1939: Available since our BSP 5, giving support for the CAN J1939 standard.
  • can-gw: CAN gateway module, used to route CAN frames.
  • vcan: Virtual Local CAN interface.

CAN Interfaces

  1. Check if your module has CAN interfaces enabled at Kernel Support on CAN (Linux) article. If not, enable it by using Device Tree Overlays on Torizon OS.

  2. Check if the interface is present by executing the command:

    # ip link show can0
    4: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
    link/can

CAN Communication Using Containers

  1. Create the container for interfacing with CAN. Create a Dockerfile with the content below.

    Dockerfile
    ARG IMAGE_ARCH=arm64v8
    # Use the parameter below for Arm 32 bits (like iMX6 and iMX7)
    # ARG IMAGE_ARCH=arm32v7
    FROM torizon/$IMAGE_ARCH-debian-base:3-bookworm
    WORKDIR /home/torizon

    RUN apt-get -y update && apt-get install -y \
    nano \
    python3 \
    python3-pip \
    python3-setuptools \
    git \
    iproute2 \
    can-utils \
    python3-can \
    && apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*

    As you have observed, the definition of our custom container image has the following packages:

    • iproute2: Which is necessary for configuring, enabling, and disabling the CAN network interfaces.
    • can-utils: A set of Linux command-line utilities for debugging CAN network.
    • Python3-CAN: A wrapper of SocketCAN for Python3.
    • git: If you want to clone example projects/libraries to interact with CAN
    • Plus, other useful tools as nano, to edit files within the container.

    The most important packages are iproute2, which allows you to configure the CAN interface, and can-utils, which allows us to send and receive CAN messages using the terminal.

  2. Build the container in the host computer:

    $ docker build -t can-torizon-sample .
  3. Compress the container in a *.tar file so you can send it to your target development board:

    $ docker save -o can-torizon-sample.tar can-torizon-sample
    $ scp can-torizon-sample.tar torizon@X.X.X.X:/home/torizon/
  4. Load your container directly from the tar file:

    # docker load -i can-torizon-sample.tar
  5. Check if the image is in the system:

    # docker image ls
    verdin-imx8mm-06612136:~$ docker image ls
    REPOSITORY TAG IMAGE ID CREATED SIZE
    can-torizon-sample latest 5ea7a31bf664 About an hour ago 203MB
  6. Run the container

    $ docker run -it --rm --name=can-test --net=host --cap-add="NET_ADMIN" \
    -v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/ \
    can-torizon-sample

The key aspect behind the setup and usage of CAN on containers with Torizon OS is the usage of the following flags when running your container:

  • --net=host : This will make Docker to uses the host's network stack for the container.
  • --cap-add=NET_ADMIN : For interacting with the network stack, this allow to modify the network interfaces.

Once within the container console, you'll have to configure the CAN Network. This process is much similar to the setup of CAN on Linux. We'll set only one CAN interface. But depending on your CoM, you may have more CAN interfaces available.

  1. When inside the container, configure the CAN0 interface with a bitrate of 500000 bps:

    ## ip link set can0 type can bitrate 500000
  2. Bring the interface up:

    ## ip link set can0 up
  3. Check if the interface is set and ready:

    ## ip link show can0
    3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can

Now you can start using applications that may connect to the CAN Network, or simply use the can-utils for testing.

For programming a Linux application in C/C++, you can use the SocketCAN API. There is also a wrapper for it in Python.

Simple testing with can-utils

One way to test if everything is OK with your CAN communication, you can do the following:

  1. Use the cansend <interface> <message> to send CAN messages on a given interface. Like for example:

    ## cansend can0 123#deadbeef
  2. Use the candump <interface> command to start listening to incoming CAN messages on a given interface. If everything worked fine, a CAN message "DEADBEEF" with ID 123 on CAN will be prompted on the terminal.

    ## candump can0
    can0 123 [4] DE AD BE EF

You can read more about can-utils on its project page.

Extra Resources



Send Feedback!