Introduction
The AM335x processor used on the Beaglebone, hosts next to the ARM main CPU two additional CPU cores called PRU (Programmable Realtime Units). This brings next to mainline linux and connectivity, also real-time, lightning fast GPIO. A driver is needed to accommodate interaction between the ARM host processor and the PRU remote processors. Although the Remoteproc driver is now standard, the UIO driver is still used because of it's simplicity (compare this example with this one). This guide is intended to document how to enable the UIO PRU driver in newer Debian Beaglebone images.
Prerequisite: a working and compatible image
First off, this guide is based on a known to be working Beaglebone image. Testing shows that there's actually only one image on Beaglebone.org that is suitable, at least, in combination with a Beaglebone Green, which is used here (see also note 1 and 2 below regarding kernels and making bootable sd-cards):
image (beaglebone.org) | UIO | Remoteproc | Remark |
---|---|---|---|
bone-debian-8.7-lxqt-armhf-2017-03-19-4gb.img | no | yes | Remoteproc hard-coded in kernel |
bone-debian-8.7-iot-armhf-2017-03-19-4gb.img | no | yes | Remoteproc hard-coded in kernel |
bone-debian-8.6-lxqt-4gb-armhf-2016-11-06-4gb.img | yes | yes | Only usable image for BBG at time of writing |
bone-debian-8.6-iot-armhf-2016-11-06-4gb.img | ? | ? | Did not boot on BBG |
bone-debian-8.6-iot-armhf-2016-12-09-4gb.img | ? | ? | Did not boot on BBG |
bone-debian-8.3-lxqt-4gb-armhf-2016-01-24-4gb.img | no | yes | Does not have .dts source files that can be used shown as "Debian 8.5 2016-05-13 4GB SD LXQT" |
After downloading the image, writing it to an sd-card and booting the Beaglebone from it, the status of the uio driver can be polled:
lsmod | grep uio
which reveals:
uio_pdrv_genirq 3923 0
uio 10524 1 uio_pdrv_genirq
This could lead to the incorrect conclusion the uio driver has already been inabled. Therefore, the uio driver needs to be enabled, and the remoteproc driver disabled.
How to Enable the UIO driver
The steps essentially boil down to the following main steps:
- enable the UIO driver and disable the Remoteproc driver in the device tree binary (dtb)
- modify eUnv.txt to use the modified dtb
- blacklist the Remoteproc drivers
The first step indicates that next to the normal way of enabling and disabling kernel drivers, modifying the device tree is needed to enable the UIO driver. As a side note, this also is the case for enabling the Wireless driver on a Beaglebone Green Wireless - it took a while to figure that out.
Locate the source files of the device tree binaries
When using the Beaglebone image downloaded from Beaglebone.org, at least the version used here, the source of the device tree binaries (dtb's) is provided in the /opt/source/ directory:
cd /opt/source/dtb-4.4-ti/
It's well possible this is also provided by the factory installed image on the EMMC of your Beaglebone. Otherwise the git repository can be cloned as well, but make sure the correct branch is selected (in this case the "4.4-ti" branch matching the kernel version of the image), by issuing the command "git clone -b 4.4-ti https://github.com/RobertCNelson/dtb-rebuilder dtb-4.4-ti --depth=1" in a suitable empty directory, e.g. /opt/source/.
Modify your dtb to enable the UIO driver
Check which board file you need to modify. As explained in the prerequisites above, each Beaglebone has it’s own .dtb file. It’s the corresponding source file that has to be modified to enable the UIO driver, for which the filename ends with .dts. In this case, the am335x-bonegreen.dts is modified as an example:
nano src/arm/am335x-bonegreen.dts
Then locate and uncomment the pruss uio part, and disable the remoteproc part:
#include "am33xx-pruss-uio.dtsi"
/* #include "am33xx-pruss-rproc.dtsi" */
Compile the board files and install by issuing the make command (assuming your're still in the /opt/source/dtb-4.4-ti directory where the Makefile is located:
make
sudo make install
Modify your uEnv.txt to use the modified dtb
Ensure the adapted device tree binary is used during boot by editing the /boot/uEnv.txt:
sudo nano /boot/uEnv.txt
and uncomment the empty "#dtb=" by mentioning the corrected dtb in there:
dtb=am335x-bonegreen.dts
Blacklist the Remoteproc drivers:
Edit or add a blacklist file /etc/modprobe.d/pruss-blacklist.conf:
sudo nano /etc/modprobe.d/pruss-blacklist.conf
By adding the the 3 lines to this file:
blacklist pruss
blacklist pruss_intc
blacklist pru-rproc
And ensure uio_pruss is of course not mentioned here as blacklisted. Then reboot the Beaglebone:
sudo reboot
Check if UIO is enabled
Test to see if the device tree file loaded successfully:
lsmod |grep uio
This should now show:
uio_pruss 4928 0
uio_pdrv_genirq 3539 0
uio 8822 2 uio_pruss,uio_pdrv_genirq
Instead of the response shown earlier. As next step, check these additional guides how to code the PRU in C, and how to share memory between the ARM host and PRU processors. To support and or give feedback, feel free to comment on the beagleboard.org forum.
Closing Remarks
The Beaglebone is a challenging, open source Single Board Computer, with huge potential, but has a steep learning curve given it's complexity and way things are dealt with and change over time causing out of date guides and the like. Hopefully this guide remains to help out long enough and gets you going with the real interesting part - programming the PRU's themselves. Enjoy!
Notes
1) Apart from using an image for the complete OS, a kernel upgrade might also be workable. The linux-image-4.4.30-ti-r64 is the kernel used in the working image mentioned above, and linux-image-4.4.14-ti-r34 is the kernel used in another project mentioned on this site. Check beaglebone.org forum for more info as it's kind of a hit and miss what's working or not due to it's ongoing development.
2) Some brief instructions how to make a bootable sd-card in Debian after downloading the preferred image. First decompress the downloaded image:
unxz bone-debian-8.6-lxqt-4gb-armhf-2016-11-06-4gb.img.xz
Then copy the disk image to the micro-sd by the easiest method found so far:
sudo dd bs=4M if=bone-debian-8.6-lxqt-4gb-armhf-2016-11-06-4gb.img of=/dev/the_device you_found_with_lsblk && sync
3) It is also worth noting, that work is ongoing to be able to select either uio or remoteproc in uEnv.txt directly. It's unclear as for now if this will make the instruction on this page still applicable or not.