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 the Debian-based TI Linux image ( as I do), the system comes with a command utility to choose and configure each pin to the mode of choice. If one is logged into the BBB, typing config-pin without any arguments gives the following output:

[ Update 12/26/2023: if the config-pin utility is not a part of the system by default, follow the directions here for getting it onto the system ] 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. However, if one power cycles the BBB, the GPIO pin configuration will be lost and will need to be set again. Quite a pain but fear not, there is a solution. Using systemd, one can create a service to configure the pins at 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. Inside the home directory, create an empty file 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 the file as a shell script (.sh). Give the file execute permissions:

sudo chmod +x <name>.sh

Navigate to the /etc/systemd/system directory and create systemd unit files for configuring the CAN lanes. For can0 (can0.service):

[Unit]
Description=can0 interface setup
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=simple
User=root
Group=root
Restart=on-failure
RestartSec=2s
RemainAfterExit=yes
ExecStartPre=/sbin/ip link set can0 type can bitrate 500000 restart-ms 10 listen-only on
ExecStartPre=/sbin/ip link set can0 txqueuelen 1000
ExecStart=/sbin/ip link set can0 up
ExecStop=/sbin/ip link set can0 down

[Install]
WantedBy=multi-user.target

Then can1 (can1.service):

[Unit]
Description=can1 interface setup
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=simple
User=root
Group=root
Restart=on-failure
RestartSec=2s
RemainAfterExit=yes
ExecStartPre=/sbin/ip link set can1 type can bitrate 500000 restart-ms 10
ExecStartPre=/sbin/ip link set can1 txqueuelen 1000
ExecStart=/sbin/ip link set can1 up
ExecStop=/sbin/ip link set can1 down

[Install]
WantedBy=multi-user.target

One can set the queue length, restart time, and baud rate to whatever is needed. Save the files. I gave the files ‘777’ as far as file permissions go.

Next, create a systemd unit file to run the pin configuration script we created earlier. I gave the unit file the same name as the script, making sure the extension is .service. The contents of the unit 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. I also set the file permissions for this file to ‘777’.

Issue the following command to start each of your new custom services:

sudo systemctl start <name>.service

Next, issue the following command and verify that the services were started:

sudo systemctl status <name>.service

Finally, issue the following command to enable the services and ensure they will run started when the system boots up:

sudo systemctl enable <name>.service

Reboot the system. To verify that the services executed 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.