EBC Exercise 30 PRU via remoteproc and RPMsg

Here's how to setup a Bone to play with the PRUs using remoteproc and RPMsg. My goals here are:
 * 1) Everything compiles on the Bone.
 * 2) The PRUs are programmed in 'C', not assembly.
 * 3) remoteproc and RPMsg are used.

A good starting place on the TI site for PRUs is http://processors.wiki.ti.com/index.php/PRU-ICSS. PRU_Training:_Hands-on_Labs has some good hands on labs, however they are all based on Code Composer Studio and I want my examples to compile and run on the bone.

Chapter 13 of Derek's Molloy's excellent Exploring BeagleBone gives many good examples of using the PRU, but he uses the older UIO interface. I want to use the new remoteproc and RPMgs.

ZeekHuge has some nice Bone-based examples that that are remoteproc and bone-compile based, so that's what I start with here.

But first, you need to get your bone set up.

Install
To start, I'm running with:

bone$ cat /ID.txt BeagleBoard.org Debian Image 2016-06-19 bone$ uname -a Linux yoder-debian-bone 4.4.12-ti-r32 #1 SMP Wed Jun 22 20:18:35 UTC 2016 armv7l GNU/Linux

You need to be running at least 4.4.12-ti-r32 for these examples to work .

Disable the HDMI
The PRUs have direct access to many pins that are also used by the HDMI. Check to see if the HDMI has been disabled.

bone$ config-pin -q P8_45 P8_45 pinmux file not found! cape-universala overlay not found run "config-pin overlay cape-universala" to load the cape If you get the message above, you need to disable your HDMI. Do it by editing /boot/uEnv.txt and uncommenting the following by removing the # in front of the dtb line:

dtb=am335x-boneblack-emmc-overlay.dtb Note the name of the file is am335x-boneblack-emmc-overlay.dtb, we'll use this later. Then reboot and try again.
 * 1) BeagleBone Black: HDMI (Audio/Video) disabled:

bone$ config-pin -q P8_45 config-pin -q P8_45 P8_45 Mode: default Direction: in Value: 0 Good the HDMI is now disabled. Later we'll use config-pin to set pins to the PRU.

Setting up the PRU compiler
The PRU compiler should already be installed. bone$ which clpru /usr/bin/clpru If not, you'll have to search around to learn how to install it. (Beyond the scope of this page.)

However some setup must be done so it can find all the libraries it needs.

bone$ export PRU_CGT=/usr/share/ti/cgt-pru bone$ cd $PRU_CGT bone$ mkdir bin bone$ cd bin bone$ ln -s `which clpru` . bone$ ln -s `which lnkpru` .

The variable PRU_CGT is used by the Makefiles and scripts to know which compiler to run. I suggest you put export PRU_CGT=/usr/share/ti/cgt-pru in your .bashrc file so it's set every time you login. The other commands only need to be run once.

Making sure remoteproc is running
If you are running 4.4.14-ti-r34 or later you have to enable remoteproc. Check for remoteproc with:

bone$ lsmod | grep pru pru_rproc             13507  0 pruss_intc             7451  1 pru_rproc pruss                 10611  1 pru_rproc

If you get the response above, remoteproc is running and you can skip the rest of this section. If not, follow these instructions from  to enable it.

Edit your device tree
bone$ cd /opt/source/dtb-4.4-ti bone$ nano src/arm/am335x-boneblack-emmc-overlay.dtb  Where am335x-boneblack-emmc-overlay.dtb is the file you remembered from above.

Now change: /* #include "am33xx-pruss-rproc.dtsi" */ to #include "am33xx-pruss-rproc.dtsi" Then bone$ make bone$ make install

Create blacklist and reboot

bone$ echo "blacklist uio_pruss" > /etc/modprobe.d/pruss-blacklist.conf bone$ reboot

bone$ lsmod | grep pru pru_rproc             13507  0 pruss_intc             7451  1 pru_rproc pruss                 10611  1 pru_rproc

Now remoteproc is running.

Installing Examples
I've found some examples that are a good starting point.

TI's examples
The examples from TI's site [git://git.ti.com/pru-software-support-package/pru-software-support-package.git] are already on the bone, but let's make them easier to find.

bone$ mkdir pru bone$ cd pru bone$ ln -s /opt/source/pru-software-support-package . bone$ cd pru-software-support-package The first lines makes a directory for keeping all your PRU file and the last commands link to the already loaded files and changes to the directory. Look around and see what's there. Be sure to checkout the ReadMe.txt file.

bone$ cat ReadMe.txt

Programmable Real-time Unit (PRU) Software Support Package release 5.0 DESCRIPTION The PRU Software Support Package is an add-on package that provides a framework and examples for developing software for the Programmable Real-time Unit sub-system and Industrial Communication Sub-System (PRU-ICSS) in the supported TI processors. The PRU-ICSS achieves deterministic, real-time processing, direct access to I/Os and meets ultra-low-latency requirements. This software package contains example PRU firmware code as well as application loader code for the host OS. The examples demonstrate the PRU capabilities to   interact with and control the system and its resources. For more details about the PRU, visit http://processors.wiki.ti.com/index.php/PRU-ICSS WHAT's INCLUDED? This package includes the following resources: DIRECTORY	CONTENTS -	       examples 	Basic PRU examples include 	PRU firmware header files labs 		Source code for step-by-step labs lib 		PRU library files and library source files pru_cape 	Demo software for the BeagleBone PRU Cape ADDITIONAL RESOURCES For more information about the PRU, visit: PRU-ICSS Wiki		http://processors.wiki.ti.com/index.php/PRU-ICSS PRU Training Slides	http://www.ti.com/sitarabootcamp PRU Evaluation Hardware	http://www.ti.com/tool/PRUCAPE Support			http://e2e.ti.com

BeagleScope
ZeekHuge has a Google Summer of Code (GSoC) 2016 project called BeagleScope that has some very nice working examples. We'll look at these in more detail. Clone a copy of your own.

bone$ cd pru bone$ git clone https://github.com/ZeekHuge/BeagleScope.git bone$ cd BeagleScope bone$ cat README.md ... What is BeagleScope ? The project, as the part of GSoC-2016, aims to provide with software support to deploy the PRUSS subsystem on AM33xx processors, as a fast and parallel data acquisition units. The PRU cores being highly optimized for I/O operations and single cycle instruction execution (mostly), are an appropriate choice for bit-banging and offloading tasks. BeagleScope uses this very feature of PRUs to offload the parallel data transactions and fast data acquisition. ...

BeagleScope examples
Now that you have everything setup, it's easy to run the BeagleScope examples.

bone$ cd BeagleScope bone$ cd docs bone$ ls BBB-ADC.pdf                      clpru_and_C_usage.notes BeagleboneBlackP8HeaderTable.pdf current_remoteproc_drivers.notes BeagleboneBlackP9HeaderTable.pdf Introductory_slides.pdf

Look around. The docs directory has some good documentation. The BeagleboneBlackP*HeaderTable.pdf files tell where the PRU registers appear on the headers.



Blinky example
Here's how to blink an LED wired to P8_45.

bone$ cd BeagleScope/examples/firmware_exmples/pru_blinky bone$ ./deploy.sh

This will run make and then install the code on the PRU and start it running.

******************************************************* This must be compiled on the BEAGLEBONE BLACK itself It was tested on 4.4.12-ti-r31 kernel version The source code for blinky ie PRU_gpioToggle was taken from pru-software-support-package and can be cloned from git clone git://git.ti.com/pru-software-support-package/pru-software-support-package.git ******NOTE: use a resistor >470 ohms to connect to the LED, I have alredy made this mistake. To continue, press any key: ... -Placing the firmware -Configuring pinmux P8_45 Mode: pruout -Rebooting Rebooting pru-core 1 Done. Blinky must be up on pin P8_45

Your LED should be blinking now. Look in deploy.sh to see how the code is loaded on PRU 1 and started running.

Now go explore the other examples. There is much to be learned.

Debugging
Debugging realtime can be a challenge. I've found a good start on a PRU debugger at https://sourceforge.net/projects/prudebug/files/latest/download. I've copied the code to github and made some simple changes. (Original version uses word addresses and which I switched to byte addresses to the addresses match the output of the linker.)