Configuring the Beaglebone Black GPIO Pins (Permanently)

The majority of the 46 GPIO pins on the Beaglebone Black have different modes of operation. For example, pin 24 on header P9 can operate as a simple GPIO, a Controller Area Network (CAN) port, among others. If one is using a Debian-based Linux OS image from elinux.org, the system comes with a helper script to choose and configure each pin to a mode of choice. The script also allows the user to query the current operating mode of an GPIO pin. If one is logged into the BBB, typing config-pin without any arguments gives the following output:

The first option allows the pins to be configured using a file as input ( I currently do not know how to do this ). The second option queries the specified GPIO pin for its supported configuration modes. The third option prints the current operation mode of the GPIO pin. The final option is how one sets the operation mode of the GPIO pin. But, if one power cycles the BBB, the GPIO pins will need to be set again. Quite a pain but fear not, there is a solution. Using systemd, one can create a Linux service to configure the pins a boot up. This is what I have done for my BBB, and now I will walk you through how to do it for yourself.

First, navigate to the home directory. For me, it is /home/debian. Inside this folder, create and open an empty shell script that will be used to setup each GPIO pin to our liking. Here is what my file looks like:

#!/bin/sh -e
# turn off LEDs 1 - 3, only 0 will be on
echo 0 > /sys/class/leds/beaglebone:green:usr1/brightness
echo 0 > /sys/class/leds/beaglebone:green:usr2/brightness
echo 0 > /sys/class/leds/beaglebone:green:usr3/brightness

# configure UART
config-pin p9.11 uart
config-pin p9.13 uart
config-pin p8.37 uart
config-pin p8.38 uart

# configure P9 GPIO ports
config-pin p9.12 gpio
config-pin p9.15 gpio
config-pin p9.23 gpio
config-pin p9.27 gpio
config-pin p9.41 gpio
# configure P8 GPIO ports
config-pin p8.11 gpio
config-pin p8.12 gpio
config-pin p8.14 gpio
config-pin p8.16 gpio
config-pin p8.18 gpio
#config-pin p8.21 gpio
#config-pin p8.23 gpio
#config-pin p8.25 gpio
config-pin p8.26 gpio
config-pin p8.27 gpio
config-pin p8.28 gpio
config-pin p8.29 gpio
config-pin p8.30 gpio
config-pin p8.31 gpio
config-pin p8.32 gpio
config-pin p8.33 gpio
config-pin p8.34 gpio
config-pin p8.35 gpio
config-pin p8.36 gpio
config-pin p8.39 gpio
config-pin p8.40 gpio
config-pin p8.41 gpio
config-pin p8.42 gpio
config-pin p8.43 gpio
config-pin p8.44 gpio
config-pin p8.45 gpio
config-pin p8.46 gpio

# configure PWM ports
config-pin p9.14 pwm
config-pin p9.16 pwm
config-pin p9.42 pwm
config-pin p8.13 pwm
config-pin p8.19 pwm

# configure CAN ports
# P9_19 -> dCAN0 Rx
# P9_20 -> dCAN0 Tx
# P9_24 -> dCAN1 Rx
# P9_26 -> dCAN1 Tx
config-pin p9.19 can
config-pin p9.20 can
config-pin p9.24 can
config-pin p9.26 can

#SPI setup
config-pin p9.28 spi_cs
config-pin p9.29 spi
config-pin p9.30 spi
config-pin p9.31 spi_sclk

exit 0

After entering all the GPIO pins and their desired modes, save and close the file. Give the file execute permissions:

sudo chmod +x <name>.sh

Next, the CAN interfaces are setup so that the hardware will stay configured across power cycles. Edit the /etc/network/interfaces file and add the following lines:

auto can0
iface can0 inet manual
pre-up /sbin/ip link set $IFACE type can bitrate 500000 restart-ms 10 listen-only on
pre-up /sbin/ip link set $IFACE txqueuelen 1000
up /sbin/ip link set up $IFACE
down /sbin/ip link set down $IFACE

auto can1
iface can1 inet manual
pre-up /sbin/ip link set $IFACE type can bitrate 500000 restart-ms 10
pre-up /sbin/ip link set $IFACE txqueuelen 1000
up /sbin/ip link set up $IFACE
down /sbin/ip link set down $IFACE

One can set the queue length, restart time, and baud rate to whatever is needed. Save the file.

Next, one needs to create a service to be run by systemd on startup. This service will reference the shell script created earlier in its execution. Navigate to the /etc/systemd/system folder. In here, create a file for your service. In my case, I give it the same name as the shell script from earlier, making sure the extension is .service and not .sh, and make sure to use ‘sudo’. In this case, I named the file xmbed-pin-config, which is the same name (without the extension) for the shell script. The contents of my service file are:

[Unit]
Description=Setup for BBB pins

[Service]
Type=simple
ExecStart=/bin/bash /home/debian/xmbed-pin-config.sh

[Install]
WantedBy=multi-user.target

Save the file. Issue the following command to start your new custom service:

sudo systemctl start <name>.service

Next, issue the following command and verify that the service was started:

sudo systemctl status <name>.service

Finally, issue this command to enable the service and ensure it will be started when the system boots up:

sudo systemctl enable <name>.service

Reboot the system. To verify that the service executed the script successfully, query a few of the pins to verify their operation mode. For example, I can query header P9 pin 24 to verify it is setup for Controller Area Network (CAN):

debian@beaglebone:~$ config-pin -q p9.24

Current mode for P9_24 is: can

No more having to set the pins to desired IO modes every time the BBB system reboots.