CAN Bus on Linux


doc link

Enabling CAN Bus Support on the Embedded Linux Development Board

SR NO Chapter Page Num
1 Hardware selection and connection This covers the basics of choosing the right hardware components and ensuring proper connections to ensure optimal performance.
2 Linux Driver & Userspace Program and CLE In this, you’ll learn about Linux drivers, the communication between user space and the kernel, and how to utilize the Command Line Environment (CLE).
3 Rough This section may be under development or covers an initial overview of the topic.

1. Introduction

For this tutorial, we will be using the MYIR Tech Development Board. Specifically, the following:

2. CAN Bus Modules

The following CAN modules are recommended. You can choose one of them:

3. Required ICs for CAN Bus Support

To enable CAN bus support on Linux boards, the following two ICs are required to establish communication between the system and the physical CAN bus network:

  1. CAN Bus Controller
  2. CAN Bus Transceiver
Client 1

1. CAN Bus Controller

Function:

Interface:

Most common: MCP2515

Datasheet

2. CAN Bus Transceiver

Function:

Interface:

Most common: TJA1050, MCP2551

Why Two ICs Are Needed

More details

Best Transceiver: MCP2561

Note: MCP2551 is not recommended for new designs; use MCP2561 instead.

Modules and Wiring

Many modules are available. Make sure they match the required configuration.

Wiring Instructions

Before proceeding, set up a serial console. For more details, refer to this link: {Insert Link}

Note: Be careful about power pins (VCC, GND). Incorrect connections can easily damage the board.

Find the SPI pins on the development board (on MYIR Tech board, pin names are written on the back of the c8mmx board).

Pin to Pin Connection Between c8mmx and MCP2515

Also, split the supply voltage for both ICs.

If using this board, some small adjustments may be required, which might need soldering skills. Otherwise, you're good to go.

For more details, check out this forum thread:

Connecting the Module

To connect the module, use the SPI pin and one more pin for GPIO interrupt. Ensure that this GPIO pin is not allocated to other features.

Client 1
SN MYD-C8MMX (ECSPI2, See back of the board) ((bank - 1) * 32) + pin MCP2515
NA J23-1: 3V3 NA VCC
gpio5.IO[13] J23-2: ECSPI2_SS0 141 CS
gpio5.IO[11] J23-3: ECSPI2_MOSI 139 SI
gpio5.IO[12] J23-4: ECSPI2_MISO 140 SO
gpio5.IO[10] J23-5: ECSPI2_SCLK 138 SCLK
NA J23-6: GND NA GND
gpio4.IO[10] J16-14: SAI1_TXFS 106 INT

1. Without level shifter connection

Without Level Shifter

2. With High speed level shifter (TXS0108E)

With Level Shifter

So here hardware is done, now moving to software part

Linux Driver & Userspace Program

To get the system working, you need to understand two key aspects:

  1. Linux Driver Setup (Kernel driver, DTS changes)
  2. User Application Tools

1. Linux Driver Setup

In Linux, there are two types of drivers for CAN:

I’ve used and preferred SocketCAN, which is the network socket-based driver. Specifically, I worked with SAE J1939 and used hardware from Microchip: MCP251x.

Additional Resources

2. User Application Tools

I recompiled the Linux image and booted from the SD card. The new DTS changes and drivers are reflected in the boot process.

You can download the modified DTS file from the following link:

Download DTS File

For the Linux config file, refer to the following directory:

{kernel source directory}/drivers/net/can/*

Alternatively, check the source on GitHub:

Linux CAN Drivers on GitHub

Kernel Configuration and Compilation

To launch the kernel menuconfig, use the following command:

bitbake -c menuconfig virtual/kernel

After making your changes, rebuild the kernel using:

bitbake virtual/kernel

My Linux Kernel Configuration for CAN Driver

This is my configuration for Linux/arm64 4.9.170 Kernel.

Menuconfig changes
Linux Kernel Configuration.
    [*] Networking support  ---> 
        <*>   CAN bus subsystem support  --->
            <*>   Raw CAN Protocol (raw access with CAN-ID filtering)
		    <*>   Broadcast Manager CAN Protocol (with content filtering)
		    <*>   CAN Gateway/Router (with netlink configuration) 
		    CAN device drivers
			    <M> Virtual Local CAN Interface (vcan)
            <*> Platform CAN drivers with Netlink support
            [*]   CAN bit-timing calculation
            CAN SPI interfaces  --->
        		<M> Microchip MCP251x SPI CAN controllers
           	[*] CAN devices debugging messages

After these changes, recompile Linux, and load it into your hardware.

Debugging & Troubleshooting

We were using MYIR Tech development board (specifically MYC-C8MMX-V2)

1. Driver fails to initialize the MCP2515 CAN controller

root@myd-imx8mm:~# modprobe can
[ 25.901538] can: controller area network core (rev 20170425 abi 9)
[ 25.907887] NET: Registered protocol family 29

root@myd-imx8mm:~# modprobe can-dev
root@myd-imx8mm:~# modprobe can-raw
[ 25.948100] can: raw protocol (rev 20170425)

root@myd-imx8mm:~# rmmod mcp251x
root@myd-imx8mm:~# modprobe mcp251x
[ 26.274264] mcp251x spi1.0: Cannot initialize MCP2515. Wrong wiring?
[ 26.280681] mcp251x spi1.0: Probe failed, err=19

root@myd-imx8mm:~# echo "8 4 1 7" > /proc/sys/kernel/printk
root@myd-imx8mm:~# rmmod mcp251x
root@myd-imx8mm:~# modprobe mcp251x
[ 94.513452] mcp251x spi1.0: MCP251x didn't enter in conf mode after reset
[ 94.520300] mcp251x spi1.0: Probe failed, err=16
[ 94.525162] mcp251x: probe of spi1.0 failed with error -16

root@myd-imx8mm:~# ip link set can0 type can bitrate 125000
Cannot find device "can0"
root@myd-imx8mm:~# ip link set up can0
Cannot find device "can0"
root@myd-imx8mm:~# ip link show can0
Device "can0" does not exist.
root@myd-imx8mm:~# ifconfig can0
can0: error fetching interface information: Device not found

Reason for this failure can be:

The best way to troubleshoot this is to use a USB Logic Analyzer. Simply connect your SPI pins to the analyzer and check according to the CAN protocol if it is sending and receiving data.

2. Probe failed

----

J1939 & CAN-utils

Installation Steps for CAN-utils

Follow the steps below for installing can-utils. More details can be found at elinux.org/Can-utils:

git clone https://github.com/linux-can/can-utils.git
cd can-utils
./autogen.sh
./configure
make
make install (with root privileges)

Bringing CAN Interface Up

Virtual Interfaces

SocketCAN also offer virtual CAN for testing purposed, with below cmds you can

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

Native Interfaces


sudo ip link set can0 type can bitrate 125000
sudo ip link set up can0

Test CAN Device


ifconfig vcan0

Useful J1939 Resources

J1939Socket

Other Development Boards

Good Explanation on J1939

A detailed explanation on J1939 can be found at: