Skip to main content
Version: BSP 7.x.y

CAN (Linux)

Introduction

CAN (Controller Area Network) is a robust communication protocol widely used in automotive and industrial systems to enable reliable data exchange between multiple units over a single differential pair (two-wire) bus.

This article will guide you on how to use the Controller Area Network (CAN) interface on Toradex's System on Modules (SoMs).

Keep in mind that Torizon OS is preferred for using the CAN interface due to its ease of use and smoother application development experience. For using CAN with Torizon, refer to How to Use CAN on Torizon OS.

Communicating with a CAN bus (ISO 11898) requires two hardware components: a CAN controller and a CAN transceiver.

  • CAN Controller: Sends and receives CAN datagrams, acting on the data-link layer. The Controller connects to the Transceiver through the CAN RX/TX signals.
  • CAN Transceiver: Transceives the datagrams to and from the Controller to the Bus, acting on the physical layer. Connects to the Controller through the CAN RX/TX signals. Connects to the Bus through the CANH/CANL differential pair.

Most Toradex System on Modules (SoMs) include a built-in CAN Controller, and some Carrier Boards include CAN Transceivers. For specific instructions for modules without CAN Controllers, refer to the CAN Interface Setup section.

On the software side, the Linux kernel provides CAN networking through the SocketCAN layer, which makes use of the network socket API to communicate with devices on the CAN bus. For a short introduction to the SocketCAN layer, please refer to the Linux Kernel Documentation.

CAN Interface Setup

Some modules require additional configuration and setup to use the CAN interface on Toradex Reference Images. This section will show you how to apply the configuration for each of these modules.

The CAN buses are enabled by default and do not need additional configuration for most Toradex SoMs. Refer to the tabs below for reference on the modules that require specific setup. If your device is not listed, proceed to the CAN Utilities section.

CAN is not a standard pin mux in the Colibri family. But you can still use CAN in Colibri modules with the following methods:

  • Connect a CAN Controller externally to the Colibri SPI interface (Enabled by default with no additional configuration). Our images provide and enable the driver for the MCP251x CAN controller by default (CONFIG_CAN_MCP251X). The Colibri Evaluation Board already includes the MCP251x controller. To check the MCP251x driver in your system, run the command below:

    # zcat /proc/config.gz | grep CONFIG_CAN_MCP251X
    CONFIG_CAN_MCP251X=y
  • Enable the internal CAN controllers manually by editing your module's Device Tree, as shown below.

To use the internal CAN controller rather than an external SPI connected controller, follow the steps below:

  1. In the kernel source code, open the imx6qdl-colibri.dtsi device tree include file:

  2. Enable the FlexCAN1 (pins 55/63) and/or FlexCAN2 (pins 178/188) interfaces in the device tree:

    arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi
    /* Optional on SODIMM 55/63 */
    &can1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan1>;
    - status = "disabled";
    + status = "okay";
    };

    /* Optional on SODIMM 178/188 */
    &can2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan2>;
    - status = "disabled";
    + status = "okay";
    };
  3. If you are using the Colibri Evaluation Board, remove jumpers JP4/JP5 and connect the FlexCAN RX/TX signals to the X38 header. This will connect the signals to the CAN transceiver, bypassing the MCP251x CAN controller.

CAN Utilities

Toradex Reference Images include the can-utils package from the Linux-CAN project for controlling your module's CAN interface.

can-utils is a fork of Pengutronix's canutils, which you can optionally build into your image and use as an alternative.

To control the CAN interfaces of your device with can-utils, follow the steps below. The example shown here controls the can0 interface on a Verdin iMX8M Plus.

  1. List the CAN networks available in your system using the ip command. Some Toradex modules have alternate names to help you identify the corresponding CAN signals on your board. In the output shown below, the can0 interface corresponds to the CAN_1 signals on the Verdin iMX8M Plus. If the alternate name is not specified, search for the can<x> node in your module's Device Tree.

    # ip addr show type can
    4: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can
    altname verdin-can1
    5: can1: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can
    altname verdin-can2
  2. Configure and start the CAN network for the interface you wish to use. The example below sets the bitrate to 500000 and activates bus error reporting. The bitrate depends on the CAN bus your module is connected to. For further configuration options, run ip link set can0 type can help.

    # ip link set can0 up type can bitrate 500000 berr-reporting on
  3. Confirm that the network is up with the command below. You should see ERROR-ACTIVE in the output, indicating that the network is active.

    # ip -details link show can0
    4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0
    can <BERR-REPORTING> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
    bitrate 500000 sample-point 0.875
    tq 25 prop-seg 37 phase-seg1 32 phase-seg2 10 sjw 5 brp 1
    flexcan: tseg1 2..96 tseg2 2..32 sjw 1..16 brp 1..1024 brp_inc 1
    flexcan: dtseg1 2..39 dtseg2 2..8 dsjw 1..4 dbrp 1..1024 dbrp_inc 1
    clock 40000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 ...
    altname verdin-can1
  4. Run the command below to send the payload 1122334455667788, with 01F as the ID.

    # cansend can1 01F#1122334455667788
  5. Run the command below to monitor the traffic in the CAN bus:

    # candump can0:0,#FFFFFFFF

Custom CAN Interface Names

If you enable custom can interfaces - for example, additional CAN through SPI controllers or the i.MX FlexCAN - the interfaces may be enumerated in a random order with every boot.

You can create udev rules to configure the CAN interfaces and set standard names, as shown below:

  1. Identify the names of the available CAN interfaces:

    # ip link
  2. Get the udev information for the CAN interfaces with udevadm. The command below shows the information for can0.

    # udevadm info -a -p $(udevadm info -q path -p /sys/class/net/can0)
  3. Based on the properties extracted in the previous step, create a rules file at /etc/udev/rules.d/. The example below configures 3 CAN interfaces:

    • CAN0: MCP251x through SPI
    • CAN1: i.MX FlexCAN 1
    • CAN2: i.MX FlexCAN 2
    11-custom-can.rules
    KERNELS=="spi0.0", SUBSYSTEMS=="spi", DRIVERS=="mcp251x", ACTION=="add", NAME="CAN0"
    KERNELS=="2090000.can", ACTION=="add", NAME="CAN1"
    KERNELS=="2094000.can", ACTION=="add", NAME="CAN2"
  4. Reload the udev rules and reboot:

    # udevadm control --reload-rules
    # reboot
  5. Confirm that the interface names are always the same with ip link.

CAN FD

Some Toradex SoMs and carrier boards support CAN FD, which can reach transfer rates of up to 8 Mbps. Note that CAN FD is backward-compatible with standard CAN.

To enable CAN FD, use the fd and dbitrate options with the ip link set command from the basic usage instructions. The following arguments configure the transfer bitrates:

  • bitrate 500000 sets the CAN transfer rate to be 500 kbps.
  • dbitrate 2000000 sets the CAN transfer rate to be 2 Mbps. This configuration will only be applied if the device is connected to a CAN FD bus.
# ip link set can0 up type can bitrate 500000 dbitrate 2000000 fd on

To send CAN FD frames, add an extra # between ID and payload in the cansend command, as shown below. For further information, refer to cansend's manpage.

# cansend can0 123##0112233445566778899AABBCCDDEEFF00

For more information about CAN FD, check the following references:

Send Feedback!