"... and no one shall work for money, and no one shall work for fame; But each for the joy of the working, and each, in his separate star, shall draw the thing as he sees it, for the god of things as they are"

-Kipling

 

The Beaglebone Black and Device Tree Overlays

Summary

This page describes how to use the Device Tree, the uEnv.txt file and the config-pin tool to set the PinMux Mode for various OCP Devices and hence determine which I/O lines are available on the P8 and P9 headers of the Beaglebone Black.

Background

The AM335x CPU used by Beaglebone Black provides a number of useful internal devices such as serial ports, SPI, I2C, A2D Converters and much more. These devices, called On-Chip-Peripherals (or OCP Devices), provide very useful interface functionality and each requires one or more I/O lines. The problem is that because there are so many OCP devices, there are many more requirements for I/O lines than there are pads on the CPU to make them available to the outside world.

The designers of the AM335x CPU reasoned that not all OCP devices would need to be used at the same time and so they set it up so that the I/O lines for the various OCP Devices can share pads on the outside of the CPU. This has the advantage of making CPU able to offer far more OCP devices than would normally be possible. It does, however, have the disadvantage that a specific OCP device may not be useable if the I/O lines it needs are already in use by some other active OCP device.

Prerequisites

Internal to the AM335x CPU, the device which does the switching of the various OCP Device I/O lines is called the PinMux. If you are not familiar with the PinMux and its operation you should read the Beaglebone Black PinMux Modes overview page before proceeding further here.

The CPU pad controlled by the PinMux output (called the PinMux pin) can have one of eight OCP Device lines directed to it and the value currently in use (0 to 7) is called the PinMux mode. At boot time there is a default mode for each PinMux pin.

In recognition of the fact that the default PinMux mode (and hence default OCP device line available on the CPU pad) might not be universally acceptable, there are methods of adjusting the settings at boot time. The mechanism currently in use is called the Device Tree. The Device Tree is a single binary file compiled up from user editable source code. It is read and applied at boot time (by the kernel) to set the initial state and usage of the PinMux pins. On the Beaglebone Black, the Device Tree binary does far more than set the initial state of the OCP Devices - the configuration of all devices on the system are controlled by it. If you would like to know more about the Device Tree and how it works please see the About the Device Tree paper.

It should be noted that many OCP devices have specific Device Driver software available and, on the Linux system, the Device Tree also specifies the loading of these Device Drivers and (typically) their mapping into the file system. Thus, the Device Tree configuration usually does far more than just set the PinMux mode for an OCP device - it will also load the appropriate Device Driver. Whether your software uses these file system (or IOCTL) based interfaces is up to you - it is possible to work with the OCP devices directly. However, user mode software (even running as root) cannot adjust the PinMux.

Since the Device Tree is such an intrinsic (and complicated) part of the boot process, many users are generally loathe to mess about with it. The source code is many thousands of lines long and an error in any one part may render the device unbootable. Accordingly, a mechanism to just "patch" specific parts of the existing configuration set up by the standard main Device Tree was developed. This "patch" is called a Device Tree Overlay and it is compiled up into a binary file from source code in a similar way to that used for main Device Tree. Device Tree Overlays can adjust the PinMux Mode and load the Device Drivers as if they were a part of the original Device Tree binary. Older versions of the Beaglebone Black operating system used a software tool called a Cape Manager to add and remove these overlays at runtime. The Cape Manager was itself a Device Driver which is why it had the relevant permissions to adjust the PinMux Mode.

The Cape Manager concept proved to be problematic and, as of early 2017, all newer releases of the Beaglebone Black operating systems have removed it and replaced it with overlays that are added as entries in the uEnv.txt file applied at boot time. This does mean that you can now only add overlays at boot time and cannot dynamically remove them without a reboot. It also means that many of the previous Cape Manager related issues have gone away - this was thought to be the better side of the deal in the trade-off

Changes made to the Device Tree or Device Tree Overlays are automatically applied upon every boot of the Beaglebone Black - they are permanent until you remove them.

In recognition of the fact that some people may wish to change the PinMux Mode dynamically (via the command line) at runtime, the config-pin utility was developed. The config-pin command enables the root user to change the PinMux mode - but it will not cause the relevant Device Drivers for the OCP Devices to be loaded. Changes made with the config-pin utility are not permanent and will need to be re-applied after each reboot.

Options for Adjusting the PinMux Mode

If you wish to adjust the state of the PinMux or add support for new peripheral devices you have three options:

  1. Edit and compile the full Device Tree and reboot.
  2. Create an overlay which adjusts the Device Tree at boot time, add it to the /boot/uEnv.txt file and reboot.
  3. In some circumstances, just using the config-pin tool to set the proper PinMux Mode may be sufficient.

Compiling and Editing the Full Device Tree

The process of editing and compiling the full Device Tree is documented in considerable detail in the About the Device Tree paper and will not be discussed here.

Setting the PinMux Mode with the config-pin Tool

The config-pin tool is installed on all newer versions of the Beaglebone Black Debian operating system. It is very easy to use and has a variety of options - just type config-pin -h to view the help file. Keep in mind that the config-pin tool will not load device drivers to support an OCP Device you enable. To do this you need to use the full Device Tree or a Device Tree Overlay.

There is also a useful tool called show-pins which will show you the state of the current PinMux settings. The show-pins tool is a clever Perl script which compiles information from various sources (including config-pin) to show you the current state of the PinMux in a nice format. You can obtain the show-pins tool from https://github.com/mvduin/bbb-pin-utils.

Setting the PinMux Mode in the uEnv.txt file with a Device Tree Overlay

The uEnv.txt file (or more specifically the /boot/uEnv.txt file) is a text file which, on the Beaglebone Black, can control a number of useful boot time options. In this section we will concentrate on how an overlay can be configured. Subsequent sections will contain pointers to pages which indicate how to disable eMMC memory, disable the video drivers (called running headless) and load the UIO driver subsystem.

Step 1: Have a look at the uEnv.txt file

You can edit the uEnv.txt file by issuing the command (as root) nano /boot/uEnv.txt. Inside the uEnv.txt file (among many other things) you will see a section that looks like

###Master Enable
enable_uboot_overlays=1
###
###Overide capes with eeprom
#uboot_overlay_addr0=/lib/firmware/.dtbo
#uboot_overlay_addr1=/lib/firmware/.dtbo
#uboot_overlay_addr2=/lib/firmware/.dtbo
#uboot_overlay_addr3=/lib/firmware/.dtbo
###
###Additional custom capes
#uboot_overlay_addr4=/lib/firmware/.dtbo
#uboot_overlay_addr5=/lib/firmware/.dtbo
#uboot_overlay_addr6=/lib/firmware/.dtbo
#uboot_overlay_addr7=/lib/firmware/.dtbo
###
###Custom Cape
#dtb_overlay=/lib/firmware/.dtbo
###
The statement enable_uboot_overlays=1 must be uncommented and set equal to a value of 1 if you wish to add overlays.

The next section is used to override the overlays supplied by Capes. It is possible for Capes to contain an EEPROM, accessible via I2C, which can supply a Device Tree Overlay at boot time in order to adjust the Beaglebone Black Device Tree. This permits the cape to modify an existing Device Tree structure in a way which will enable the Cape to operate. In operation, it is exactly analogous to a user specifying an overlay manually except that it is automatically pulled from the Cape via I2C.

#uboot_overlay_addr0=/lib/firmware/.dtbo
#uboot_overlay_addr1=/lib/firmware/.dtbo
#uboot_overlay_addr2=/lib/firmware/.dtbo
#uboot_overlay_addr3=/lib/firmware/.dtbo
Of course you may not wish to use the Device Tree Overlay supplied by the Cape and and would instead prefer to use one of a custom design. If this is the case, then you will not want to add it manually since that would cause the boot process to attempt to apply both of them. Instead you would probably prefer to replace the one which would normally be provided by the Cape with yours. The four lines in the first section will do this - an overlay specified here will be used instead of the one supplied by the Cape. The four lines correspond to the four I2C addresses (0x54=="uboot_overlay_addr0", 0x55=="...addr1", 0x56=="...addr2" and , 0x57=="...addr3") used by the Capes for this purpose.

The only way to disable the use of a Cape overlay is to uncomment the appropriate #disable_uboot_overlay_addr[0-3]=1 line in the uEnv.txt file. This line is not shown in the above text. If you do not have a Cape providing a Device Tree overlay on the appropriate address, then an overlay specified in one of these lines will be applied as normal.

Assuming that you do not wish to override a Device Tree Overlay provided by a Cape and wish to apply your own custom written one, then you will want to use one of the subsequent five lines.

###
###Additional custom capes
#uboot_overlay_addr4=/lib/firmware/.dtbo
#uboot_overlay_addr5=/lib/firmware/.dtbo
#uboot_overlay_addr6=/lib/firmware/.dtbo
#uboot_overlay_addr7=/lib/firmware/.dtbo
###
###Custom Cape
#dtb_overlay=/lib/firmware/.dtbo
The file containing the compiled binary of the Device Tree overlay can be specified in any of the uboot_overlay_addr[4-7] lines and/or in the dtb_overlay line. These five lines are functionally identical and are interchangeable. The dtb_overlay line was apparently put in during testing and never removed. It could just as well have been named uboot_overlay_addr8.

Step 2: Edit your Device Tree Overlay

The content of the overlay you use will necessarily be specific to the OCP device you are configuring. Shown below is a Device Tree Overlay from the Tilo Project which sets up two PinMux pins so that they can be used by the Programmable Realtime Unit (PRU1) as outputs to drive a stepper motor. The contents of this file will not be discussed here - see the About the Device Tree paper for more information.

    /dts-v1/;
    /plugin/;

    /{
        compatible = "ti,beaglebone", "ti,beaglebone-black";
        part-number = "Tilo-00A0";
        version = "00A0";
        fragment@0 {
            target = <&am33xx_pinmux>;
            __overlay__ {
                pinctrl_test: TiloPRU0OutputPins {
                    pinctrl-single,pins = <
                        0x0A0 0x25 /* P8_45 70 OUTPUT MODE5 - pru1 r30_0 */
                    >;
                };
            };
        };

        fragment@1 {
            target = <&ocp>;
            __overlay__ {
                test_helper: helper {
                    compatible = "bone-pinmux-helper";
                    pinctrl-names = "default";
                    pinctrl-0 = <&pinctrl_test>;
                    status = "okay";
                };
            };
        };
    };

Step 3: Compile your Device Tree Overlay

Once you have configured the source for your Device Tree Overlay, you will need to compile it. To do this the Device Tree Compiler (dtc) must be used. This tool is installed by default on all recent versions of the Beaglebone Black operating system. In the following example, the name of the above Device Tree file is Tilo-00A0.dts and the resulting binary will be Tilo-00A0.dtbo.

dtc -W no-unit_address_vs_reg -O dtb -o Tilo-00A0.dtbo -b 0 -@ Tilo-00A0.dts
Note that the name Tilo-00A0 also appears in the Device Tree Source. The -W no-unit_address_vs_reg flag is just in the command to prevent the output of a meaningless warning which can be ignored.

Step 4: Copy your Device Tree Overlay to /lib/firmware

The uEnv.txt file needs to read the binary file for the Device Tree Overlay from the directory /lib/firmware - so copy it in with all of the other ones already present there.

cp Tilo-00A0.dtbo /lib/firmware/

Step 5: Edit the Appropriate Line in the uEnv.txt file

Simply placing the overlay binary in /lib/firmware is not enough to make it take effect. You need to edit the appropriate section of the /boot/uEnv.txt file as shown below.

###Additional custom capes
uboot_overlay_addr4=/lib/firmware/Tilo-00A0.dtbo
#uboot_overlay_addr5=/lib/firmware/.dtbo
#uboot_overlay_addr6=/lib/firmware/.dtbo
...
Remember to un-comment the line! Note that the uboot_overlay_addr4 line does not have a # character preceding it.

Step 6: Record the Existing PinMux State

It is useful at this point to record the existing state of the PinMux configuration so that you can see if the changes have taken effect. The easy way to do this is with the show-pins script discussed previously.
show-pins > sp1.txt

Step 7: Reboot the Beaglebone Black

The changes you made to the uEnv.txt file will only take effect after a reboot. So cycle the power or issue the command

reboot now

Step 8: Check the New PinMux State

After the reboot completes, the next step is to check to see if the PinMux configuration has changed.
show-pins > sp2.txt
diff sp1.txt sp2.txt
< P8.45 / hdmi / sysboot 0          40 fast rx      7 gpio 2.06
---
> P8.45 / hdmi / sysboot 0          40 fast    down 5 pru 1 out 0      ocp/helper (TiloPRU0OutputPins)
Note that the name TiloPRU0OutputPins present in the original Device Tree Source file will also appear in the above list (for diagnostic purposes) so you can see which overlay last changed the PinMux state of a particular pin.

How to Disable the eMMC Memory on the Beaglebone Black

This is quite a simple procedure in later versions of the Beaglebone Black operating system. Just comment out the appropriate line in the uEnv.txt file. Please see the Disabling The EMMC Memory On The Beaglebone Black page.

How to disable the Video on the Beaglebone Black and Run Headless

This is quite a simple procedure in later versions of the Beaglebone Black operating system. Just comment out the appropriate line in the uEnv.txt file. Please see the Disabling Video On The Beaglebone Black And Running Headless page.

How to Enable the UIO Drivers on the Beaglebone Black

There are two mechanisms available to load programs into the Programmable Realtime Units on the Beaglebone Black. You can use UIO which takes a simple binary image or RProc which uses compiled ELF binaries. Later versions of the Beaglebone Black enable only RProc by default . Please see the Enabling the UIO Drivers on the Beaglebone Black page for more information.

License

The contents of this web page are provided "as is" without any warranty of any kind and without any claim to accuracy. Please be aware that the information provided may be out-of-date, incomplete, erroneous or simply unsuitable for your purposes. Any use you make of the information is entirely at your discretion and any consequences of that use are entirely your responsibility. All source code is provided under the terms of the MIT License.

Acknowledgements

Various internet resources were used to help understand the workings of the Beaglebone Black. Especially useful were the Beaglebone Black Forums. Thank you RobertCNelson!