Learn How to Use the BeagleBone's Digital I/O
Courtesy of All About Circuits
Get started with the general purpose I/O on the BeagleBone Black!
The bash shell is the simplest way to manipulate the BeagleBone's I/O. Why? You may have heard that, on Linux, everything is a file. The bash shell provides an easy way to interface with files in a Linux system. BeagleBone Black is no exception to this rule since it runs on Linux—even the BeagleBone’s GPIO are files! It takes a little work to dig down to them.
Step 1 for using the GPIO is to export the chosen pin as a GPIO. The process is pretty simple and involves a simple file write using the 'echo' command:
$ echo 67 > /sys/class/gpio/export
What's this command’s purpose? It seems like nothing happened to the board! Well, something did happen with the board, it just isn’t very obvious. The BeagleBone is built around the TI Sitara processor. Like most modern processors, the Sitara family is loaded with pins to interface with outside devices. Most of these pins can perform multiple functions, making it very convenient. These functions range in complexity, from simple tasks, like the GPIO function we'll be setting up in a minute, to extremely complex tasks, like a part of a PCIe bus or an SGMII network.
The tradeoff for this range of functionality is that you can't perform all of a pin’s functions at once. Instead, these pins are multiplexed into a port on the processor's internal bus. That means you have to select the function that you want your chosen pin to perform. The `echo` command is writing the number 67 into the file '/sys/class/gpio/export'. This tells the system that we want to use pin 67 on the board as a GPIO and that the processor should propagate those settings throughout the system. The exact details of this process are complicated and outside the scope of a single article. Once you've run this command, you'll notice that the directory /sys/class/gpio/' has an extra folder:
$ ls /sys/class/gpio
export gpio67 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
When we 'echo'-ed 67 into that file, this told the system to export the settings for GPIO_67. It responded by building the folder labeled 'gpio67'. We get the following structure when we examine the contents of this:
$ ls -al /sys/class/gpio/gpio67
drwxr-xr-x 3 root root 0 Jan 1 00:14 .
drwxr-xr-x 7 root root 0 Jan 1 00:00 ..
-rw-r--r-- 1 root root 4096 Jan 1 00:42 active_low
-rw-r--r-- 1 root root 4096 Jan 1 00:14 direction
-rw-r--r-- 1 root root 4096 Jan 1 00:43 edge
drwxr-xr-x 2 root root 0 Jan 1 00:42 power
lrwxrwxrwx 1 root root 0 Jan 1 00:41 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Jan 1 00:14 uevent
-rw-r--r-- 1 root root 4096 Jan 1 00:20 value
There are two files in our new folder, 'gpio67', that are of particular interest. The first is the `direction` file. You should see this output when you run the command `$ cat /sys/class/gpio/gpio67/direction`,:
$ cat /sys/class/gpio/gpio67/direction
If you're familiar with bare metal embedded processors (i.e. PIC, AVR, HCS08), you've most likely heard of a register called the data direction register. If so, you are welcome to skip the rest of this paragraph.
For those of you who are sticking with us: the data direction register dictates which way data can flow out of a GPIO port. There are only two options: in or out. Setting this register up for a certain GPIO pin usually involves finding the right register, then finding the right bit within that register, and lastly writing a nice little 'and' statement in C to set or clear that bit.
This isn’t the case for the BeagleBone! When we exported GPIO_67, the BeagleBone created a nice little file to read the processor's data direction register and then give it back to us in an easy to read format. Instead of a complex mash of hexadecimal, we get the two simple values: 'in' or 'out'. As you may have guessed from the earlier 'cat' command, this shift register’s default state is 'in'. It can read in data on that pin into the processor, but it can't affect the state of GPIO_67. Let's change it so we can see that pin's output in the real world! This can be done by running another 'echo' command and using 'cat' to verify that it worked:
$ echo out > /sys/class/gpio/gpio67/direction
$ cat /sys/class/gpio/gpio67/direction
We've changed the I/O's data direction from an input to an output. Now let's make it do something!
There Is a Light and It Sometimes Goes Out
The next step requires us to build a simple circuit using a single 1 kOhm resistor and an LED in your favorite color. You'll need to connect one of the LED’s pins to pin 2 of header P8 on the BeagleBone. The other end can go into any row of a solderless breadboard. Connect one of the resistor’s pins to the same row on the bread that the LED is plugged into, and the other into GPIO_67, which can be found on pin 8 of header P.
After that, run the following commands. If everything is tied together properly, you will see the LED turn on with one command and off with the other.
$ echo 1 > /sys/class/gpio/gpio67/value
$ echo 0 > /sys/class/gpio/gpio67/value
This works on the same principle as the last set of writes to `/sys/class/gpio/gpio67/value`—the only difference between the commands is what value gets written into each file. Drawing another parallel to more basic embedded systems, the `value` file is similar to a port data output register. By writing a `1` into it, you're setting the pin to a voltage high of 3.3V. Writing a `0` will set it to a voltage low and pulls the pin to ground.
Wrapping Up with a Simple Blinking Script
We can chain all of our commands together into a really simple script to toggle the LED on and off every half second:
if [ ! -e /sys/class/gpio/gpio67/value ]
echo 67 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio67/direction
while [ True ]
echo 1 > /sys/class/gpio/gpio67/value
echo 0 > /sys/class/gpio/gpio67/value
This script will run forever—in order to cancel it, you need to press `Ctrl c` to get back into a Linux terminal. You can copy the code from the excerpt above into your BeagleBone Black or do it from git using this repository.
And now you have a simple way to toggle GPIOs on a BeagleBone Black. Pretty easy, right?
What all have you tied your GPIO to? Made anything cool? Leave a comment and let us know what you're reading with your BeagleBones!