Running a Program; Configuring Pins¶
There are a lot of details in compiling and running PRU code. Fortunately those details are captured in a common Makefile that is used throughout this book. This chapter shows how to use the Makefile to compile code and also start and stop the PRUs.
Note
The following are resources used in this chapter:
Getting Example Code¶
Problem¶
I want to get the files used in this book.
Solution¶
It’s all on a GitHub repository.
bone$ cd /opt/source
bone$ git clone https://git.beagleboard.org/beagleboard/pru-cookbook-code
bone$ cd pru-cookbook-code
bone$ sudo ./install.sh
Note
#TODO#: The version of code used needs to be noted in the documentation.
Note
#TODO#: Why is this documented in multiple places?
Compiling with clpru and lnkpru¶
Problem¶
You need details on the c compiler, linker and other tools for the PRU.
Solution¶
The PRU compiler and linker are already installed on many images.
They are called clpru
and lnkpru
. Do the following to see if clpru
is installed.
bone$ which clpru
/usr/bin/clpru
Tip
If clpru
isn’t installed, follow the instructions at
https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#TI_PRU_Code_Generation_Tools
to install it.
bone$ sudo apt update
bone$ sudo apt install ti-pru-cgt-installer
Details on each can be found here:
In fact there are PRU versions of many of the standard code generation tools.
code tools¶
bone$ ls /usr/bin/*pru
/usr/bin/abspru /usr/bin/clistpru /usr/bin/hexpru /usr/bin/ofdpru
/usr/bin/acpiapru /usr/bin/clpru /usr/bin/ilkpru /usr/bin/optpru
/usr/bin/arpru /usr/bin/dempru /usr/bin/libinfopru /usr/bin/rc_test_encoders_pru
/usr/bin/asmpru /usr/bin/dispru /usr/bin/lnkpru /usr/bin/strippru
/usr/bin/cgpru /usr/bin/embedpru /usr/bin/nmpru /usr/bin/xrefpru
See the PRU Assembly Language Tools for more details.
Making sure the PRUs are configured¶
Problem¶
When running the Makefile for the PRU you get and error about /dev/remoteproc
is missing.
Solution¶
Edit /boot/uEnv.txt
and enble pru_rproc by doing the following.
bone$ sudo vi /boot/uEnv.txt
Around line 40 you will see:
###pru_rproc (4.19.x-ti kernel)
uboot_overlay_pru=AM335X-PRU-RPROC-4-19-TI-00A0.dtbo
Uncomment the uboot_overlay
line as shown and then reboot.
/dev/remoteproc
should now be there.
bone$ sudo reboot
bone$ ls -ls /dev/remoteproc/
total 0
0 lrwxrwxrwx 1 root root 33 Jul 29 16:12 pruss-core0 -> /sys/class/remoteproc/remoteproc1
0 lrwxrwxrwx 1 root root 33 Jul 29 16:12 pruss-core1 -> /sys/class/remoteproc/remoteproc2
Compiling and Running¶
Problem¶
I want to compile and run an example.
Solution¶
Change to the directory of the code you want to run.
bone$ cd pru-cookbook-code/06io
bone$ ls
gpio.pru0.c Makefile setup.sh
Source the setup file.
bone$ source setup.sh
TARGET=gpio.pru0
PocketBeagle Found
P2_05
Current mode for P2_05 is: gpio
Current mode for P2_05 is: gpio
Now you are ready to compile and run. This is automated for you in the Makefile
bone$ make
/opt/source/pru-cookbook-code/common/Makefile:27: MODEL=TI_AM335x_BeagleBone_Green_Wireless,TARGET=gpio.pru0,COMMON=/opt/source/pru-cookbook-code/common
- Stopping PRU 0
CC gpio.pru0.c
"/opt/source/pru-cookbook-code/common/prugpio.h", line 53: warning #1181-D: #warning directive: "Found else"
LD /tmp/vsx-examples/gpio.pru0.o
- copying firmware file /tmp/vsx-examples/gpio.pru0.out to /lib/firmware/am335x-pru0-fw
- Starting PRU 0
write_init_pins.sh
MODEL = TI_AM335x_BeagleBone_Green_Wireless
PROC = pru
PRUN = 0
PRU_DIR = /sys/class/remoteproc/remoteproc1
rm /tmp/vsx-examples/gpio.pru0.o
Congratulations, your are now running a PRU. If you have an LED attached to
P9_11
on the Black, or P2_05
on the Pocket, it should be blinking.
Discussion¶
The setup.sh
file sets the TARGET
to the file you want to compile.
Set it to the filename, without the .c
extension (gpio.pru0
).
The file extension .pru0
specifies the number of the PRU you are using
(either 1_0
, 1_1
, 2_0
, 2_1
on the AI or 0
or 1
on the others)
You can override the TARGET
on the command line.
bone$ cp gpio.pru0.c gpio.pru1.c
bone$ export TARGET=gpio.pru1
Notice the TARGET
doesn’t have the .c
on the end.
You can also specify them when running make
.
bone$ cp gpio.pru0.c gpio.pru1.c
bone$ make TARGET=gpio.pru1
The setup file also contains instructions to figure out which Beagle you are running and then configure the pins accordingly.
gpio_setup.sh
Line |
Explanation |
---|---|
2-5 |
Set which PRU to use and which file to compile. |
7 |
Figure out which type of Beagle we have. |
9-21 |
Based on the type, set the pins. |
23-28 |
Configure (set the pin mux) for each of the pins. |
Tip
The BeagleBone AI has it’s pins preconfigured at boot time, so there’s no
need to use config-pin
.
The Makefile
stops the PRU, compiles the file and moves it where it will
be loaded, and then restarts the PRU.
Stopping and Starting the PRU¶
Problem¶
I want to stop and start the PRU.
Solution¶
It’s easy, if you already have TARGET
set up:
bone$ make stop
- Stopping PRU 0
stop
bone$ make start
- Starting PRU 0
start
See dmesg Hw to see how to tell if the PRU is stopped.
This assumes TARGET
is set to the PRU you are using.
If you want to control the other PRU use:
bone$ cp gpio.pru0.c gpio.pru1.c
bone$ make TARGET=gpio.pru1
bone$ make TARGET=gpio.pru1 stop
bone$ make TARGET=gpio.pru1 start
The Standard Makefile¶
Problem¶
There are all sorts of options that need to be set when compiling a program. How can I be sure to get them all right?
Solution¶
The surest way to make sure everything is right is to use our
standard Makefile
.
Discussion¶
It’s assumed you already know how Makefiles work. If not, there are
many resources online that can bring you up to speed.
Here is the local Makefile
used throughout this book.
1include /var/lib/cloud9/common/Makefile
Each of the local Makefiles refer to the same standard Makefile. The details of how the Makefile works is beyond the scope of this cookbook.
Fortunately you shouldn’t have to modify the Makefile.
The Linker Command File - am335x_pru.cmd¶
Problem¶
The linker needs to be told where in memory to place the code and variables.
Solution¶
am335x_pru.cmd
is the standard linker command file that tells the linker
where to put what for the BeagleBone Black and Blue, and the Pocket.
The am57xx_pru.cmd
does the same for the AI.
Both files can be found in /var/lib/cloud9/common
.
am335x_pru.cmd
The cmd file for the AI is about the same, with appropriate addresses for the AI.
Discussion¶
The important things to notice in the file are given in the following table.
AM335x_PRU.cmd important things¶
Line |
Explanation |
---|---|
16 |
This is where the instructions are stored. See page 206 of the AM335x Technical Reference Manual rev. P Or see page 417 of AM572x Technical Reference Manual for the AI. |
22 |
This is where PRU 0’s DMEM 0 is mapped. It’s also where PRU 1’s DMEM 1 is mapped. |
23 |
The reverse to above. PRU 0’s DMEM 1 appears here and PRU 1’s DMEM 0 is here. |
26 |
The shared memory for both PRU’s appears here. |
72 |
The .text section is where the code goes. It’s mapped to IMEM |
73 |
The ((stack)) is then mapped to DMEM 0. Notice that DMEM 0 is one bank |
of memory for PRU 0 and another for PRU1, so they both get their own stacks. |
|
74 |
The .bss section is where the heap goes. |
Why is it important to understand this file? If you are going to store things in DMEM, you need to be sure to start at address 0x0200 since the stack and the heap are in the locations below 0x0200.
Loading Firmware¶
Problem¶
I have my PRU code all compiled and need to load it on the PRU.
Solution¶
It’s a simple three step process.
Stop the PRU
Write the
.out
file to the right place in/lib/firmware
Start the PRU.
This is all handled in the The Standard Makefile.
Discussion¶
The PRUs appear in the Linux file space at /dev/remoteproc/
.
Finding the PRUs¶
bone$ cd /dev/remoteproc/
bone$ ls
pruss-core0 pruss-core1
Or if you are on the AI:
bone$ cd /dev/remoteproc/
bone$ ls
dsp1 dsp2 ipu1 ipu2 pruss1-core0 pruss1-core1 pruss2-core0 pruss2-core1
You see there that the AI has two pairs of PRUs, plus a couple of DSPs and other goodies.
Here we see PRU 0 and PRU 1 in the path. Let’s follow PRU 0.
bone$ cd pruss-core0
bone$ ls
device firmware name power state subsystem uevent
Here we see the files that control PRU 0. firmware
tells where in /lib/firmware
to look for the code to run on the PRU.
bone$ cat firmware
am335x-pru0-fw
Therefore you copy your .out
file to /lib/firmware/am335x-pru0-fw
.
Configuring Pins for Controlling Servos¶
Problem¶
You want to configure the pins so the PRU outputs are accessible.
Solution¶
It depends on which Beagle you are running on. If you are on the AI or Blue, everything is already configured for you. If you are on the Black or Pocket you’ll need to run the following script.
servos_setup.sh
Discussion¶
The first part of the code looks in /proc/device-tree/model
to see which Beagle is running. Based on that it
assigns pins
a list of pins to configure. Then the last part of the script loops through each of the pins and configures it.
Configuring Pins for Controlling Encoders¶
Problem¶
You want to configure the pins so the PRU inputs are accessible.
Solution¶
It depends on which Beagle you are running on. If you are on the AI or Blue, everything is already configured for you. If you are on the Black or Pocket you’ll need to run the following script.
encoder_setup.sh
Discussion¶
This works like the servo setup except some of the pins are configured as to the hardware eQEPs and other to the PRU inputs.