Electronic – BeagleBone Black CAN bus setup

beaglebone blackcan

I am trying to connect to a CAN bus network with my BeagleBone Black and SN65HVD230. I've connected it like in the picture.

I am running:

root@beaglebone:~# cat /etc/dogtag BeagleBoard.org BeagleBone Debian
Image 2014-04-23

I loaded kmodules:

sudo modprobe can
sudo modprobe can-dev
sudo modprobe can-raw

Checked it:

root@beaglebone:~# lsmod |grep can
can_raw                 4733  0
can_dev                 7957  0
can                    21085  1 can_raw

And then commands:

root@beaglebone:~# sudo ip link set can0 up type can bitrate 500000
Cannot find device "can0"

The command fails. How could I fix this problem?

There are some overlays thing that needs to be set up, but one of the capes (SerialCape) documentation says that latest Debian doesn't have to do any changes, and it is all incorporated already. I am not using cape, but the only difference is that I've connected to my pins directly with the driver itself.

SN65HVD230

Enter image description here

Best Answer

There is concept called device tree overlay and you can think of it as request for specific pin setup on the device itself.

Some pins on the board are by default dedicated for specific purpose, SPI or I2C or just general purpose but some like CAN need to be defined to be used and that's the thing we need to do.

Folder /lib/firmware contains list of pre-configured binary overlay files which could be loaded and that would setup specific list of pins for specific purpose.

At the beginning those file are defined as source file which are regular text file with some specific syntax but in the moment we want to use them we need to compile them with dtc command.This is the reason why we have dts extension for the source and dtbo for binary.

So the process for CAN goes as follows:

Inside /lib/firmware create file BB-DCAN1-00A0.dts :

/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "dcan1pinmux";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            dcan1_pins_s0: dcan1_pins_s0 {
                pinctrl-single,pins = <
                    0x180 0x12  /* d_can1_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */
                    0x184 0x32  /* d_can1_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */
                >;
            };
        };
    };

    fragment@1 {
        target = <&dcan1>;
        __overlay__ {
             #address-cells = <1>;
             #size-cells = <0>;

             status = "okay";
             pinctrl-names = "default";
             pinctrl-0 = <&dcan1_pins_s0>;
        };
    };
};

Now it is needed to create overlay binary with the following command in the same directory:

root@host:/lib/firmware# dtc -O dtb -o BB-DCAN1-00A0.dtbo -b 0 -@ BB-DCAN1-00A0.dts

Finally execute:

 root@host:/lib/firmware#echo BB-DCAN1 > /sys/devices/bone_capemgr.*/slots

Now load kernel modules:

root@host# modprobe can
root@host# modprobe can-dev
root@host# modprobe can-raw

Build can tools:

root@host# svn co svn://svn.berlios.de/socketcan/trunk
root@host# cd trunk/can-utils/
root@host# make

Setup bus speed:

root@host# ip link set can0 up type can bitrate 500000
root@host# ifconfig can0 up