Ben Brown bio photo

Ben Brown

Electronics and Embedded Systems Engineering

Email Twitter Facebook Github

Contents

Enabling CAN Bus on the Beaglebone Green by SeeedStudio

Normally when I look to enable the CAN bus on the beaglebone black I have always followed the first guide I find online, however with the Beaglebone Green it comes with a newer debian image that does not support most of the documented methods of enabling CAN Bus (from around 2013).

Modprobe

We need to load the appropriate kernal drivers, this can be achieved by :

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

DTS Files

Now we do not need to compile the dts file anymore, instead the fully compiled file is already available in the filesystem for us, we meerly need to enable it. Thus we only need to run :

echo BB-CAN1 > /sys/devices/bone_capemgr.9/slots

As root (NOT SUDO) to enable the overlay.

Note: On newer debian systems the bone_capemgr folder does not appear to exist, I am not sure where it has gone, however I have found that loading the overlay automatically at boot appears to still work really well.

And then

sudo ip link set can0 up type can bitrate 250000

To bring up the interface (I check this by looking for can0 in ifconfig)

Automatically loading the CAN interface at system boot

The Beaglebone provides a convient method for enabling and disabling overalys at the boot of the device. This is automatically handled by the uEnv.txt file in /boot/ By adding ā€˜,BB-CAN1ā€™ to the end of the cape_enable line we can automatically load this overlay at device boot time.

My full file is shown below for reference :

[email protected]:/boot$ cat uEnv.txt
#Docs: http://elinux.org/Beagleboard:U-boot_partitioning_layout_2.0

uname_r=3.8.13-bone71.1
#dtb=
cmdline=quiet init=/lib/systemd/systemd

##Example
#cape_disable=capemgr.disable_partno=
#cape_enable=capemgr.enable_partno=BB-CAN1
cape_enable=capemgr.enable_partno=BB-UART2,BB-CAN1

##Disable HDMI/eMMC
#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN,BB-BONE-EMMC-2G

##Disable HDMI
#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN

##Disable eMMC
#cape_disable=capemgr.disable_partno=BB-BONE-EMMC-2G

##Audio Cape (needs HDMI Audio disabled)
#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI
#cape_enable=capemgr.enable_partno=BB-BONE-AUDI-02


##enable BBB: eMMC Flasher:
#cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh

uuid=47da1207-5719-4b55-a1db-1002ab2e7910

Now once I rebooted the device we automatically have the overlay loaded at system boot, this can be verified by :

cat /sys/devices/bone_capemgr.9/slots
 0: 54:PF---
 1: 55:PF---
 2: 56:PF---
 3: 57:PF---
 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
 5: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART2
 6: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-CAN1

Where you can see the status of the loaded overlays above, a ā€˜Lā€™ means that the overlay is loaded and active.

Bringing up the interface

As my bus is running at 250k baud for the CAN interface, the following line configures the speed and brings up the connection:

sudo ip link set can0 up type can bitrate 250000
sudo ifconfig can0 up

Bringing up the interface automatically

In order to bring this interface up automatically at boot, I created the following init.d script based on the skeleton file provided by init.d

[email protected]:/etc/init.d$ cat can0.sh
#!/bin/sh
### BEGIN INIT INFO
# Provides:          Init the can0 Interface
# Required-Start:    $remote_fs $syslog networking
# Required-Stop:     $remote_fs $syslog networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: can0 init
# Description:       This file brings up the can0 interface at 250k
### END INIT INFO

# Author: Ben Brown <[email protected]>
#
# Please remove the "Author" lines above and replace them
# with your own name if you copy and modify this script.

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Description of the service"
NAME=daemonexecutablename
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS="--options args"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

#
# Function that starts the daemon/service
#
do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        ip link set can0 up type can bitrate 250000;
        ifconfig can0 up;
        return 0;
        # Add code here, if necessary, that waits for the process to be ready
        # to handle requests from services started subsequently which depend
        # on this one.  As a last resort, sleep for some time.
}

#
# Function that stops the daemon/service
#
do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        ifconfig can0 down;
        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        # If the above conditions are not satisfied then add some other code
        # that waits for the process to drop all resources that could be
        # needed by services started subsequently.  A last resort is to
        # sleep for some time.
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
        #
        # If the daemon can reload its configuration without
        # restarting (for example, when it is sent a SIGHUP),
        # then implement that here.
        #
        ifconfig can0 down
        ip link set can0 up type can bitrate 250000
        ifconfig can0 up

        return 0
}

case "$1" in
  start)
        do_start
        ;;
  stop)
        do_stop
        ;;
  restart|force-reload)
        #
        # If the "reload" option is implemented then remove the
        # 'force-reload' alias
        #
        do_stop
                do_start
        ;;
  *)
        #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
        exit 3
        ;;
esac

:


The above script will need to be give the executable bit to enable execution by running :

sudo chmod +x can0.sh

Next we need to update rc to it knows about it by running :

sudo update-rc.d can0.sh defaults