Skip to content

Instantly share code, notes, and snippets.

@jrockway
Last active March 5, 2018 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrockway/03afa853940634abe588c30644ac9cbe to your computer and use it in GitHub Desktop.
Save jrockway/03afa853940634abe588c30644ac9cbe to your computer and use it in GitHub Desktop.

How to make an LED blink in 238473 difficult steps using the PRU on your Beaglebone Black.

Grab https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/pru_blinky.

The deploy script does not work and is totally wrong. But we can make it work anyway.

First, the prerequsites.

Kernel:

$ uname -a
Linux beaglebone 4.9.82-ti-r102 #1 SMP PREEMPT Thu Feb 22 01:16:12 UTC 2018 armv7l GNU/Linux

You can get this with /opt/scripts/tools/update_kernel.sh.

Now you need to make the PRUs available to the OS via a uboot overlay.

uEnv.txt:

enable_uboot_overlays=1
disable_uboot_overlay_emmc=1
disable_uboot_overlay_video=1
disable_uboot_overlay_audio=1
disable_uboot_overlay_wireless=1
disable_uboot_overlay_adc=1

uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-9-TI-00A0.dtbo # note the 4-9, the default uEnv.txt uses the 4-4 file!
enable_uboot_cape_universal=1

I don't know if you need to disable emmc, video, audio, wireless, or the adc. I disabled them because it's 5 less things to debug.

(Actually, I ended up succeeding by only disabling video.)

Reboot.

Now, clone the beaglescope repository and build the firmware:

$ cd BeagleScope/examples/firmware_exmples/pru_blinky/PRU_gpioToggle
$ export PRU_CGT=/usr/share/ti/cgt-pru
$ make

(Note that you may need to link /usr/bin into /usr/share/ti/cgt-pru/bin for Reasons.)

Glorious successful build output:

************************************************************
Building project: PRU_gpioToggle

Building file: PRU_gpioToggle.c
Invoking: PRU Compiler
/usr/share/ti/cgt-pru/bin/clpru --include_path=/usr/share/ti/cgt-pru/include --include_path=../../../include --include_path=../../../include/am335x -v3 -O2 --display_error_number --endian=little --hardware_mac=on --obj_directory=gen --pp_directory=gen -ppd -ppa -fe gen/PRU_gpioToggle.object PRU_gpioToggle.c

Building target: gen/PRU_gpioToggle.out
Invoking: PRU Linker
/usr/share/ti/cgt-pru/bin/clpru -v3 -O2 --display_error_number --endian=little --hardware_mac=on --obj_directory=gen --pp_directory=gen -ppd -ppa -z -i/usr/share/ti/cgt-pru/lib -i/usr/share/ti/cgt-pru/include --reread_libs --warn_sections --stack_size=0x100 --heap_size=0x100 -o gen/PRU_gpioToggle.out gen/PRU_gpioToggle.object -mgen/PRU_gpioToggle.map ./AM335x_PRU.cmd --library=libc.a --library=../../../lib/rpmsg_lib.lib
<Linking>
Finished building target: gen/PRU_gpioToggle.out

Output files can be found in the "gen" directory

Finished building project: PRU_gpioToggle
************************************************************

When the build outputs that many stars you know it's gonna be good.

We are going to run this in PRU0.

Copy the firwmare to the location for PRU0:

$ sudo cp gen/PRU_gpioToggle.out /lib/firmware/am335x-pru0-fw

As an aside, I think you can override this location, but we won't.

Now here's where we go totally off the rails relative to the deploy.sh included with the example. For some reason, it wants to use the P8_45 pin. This pin is not available to PRU0, but P9_31 is:

pinout

Make this pin available to the PRU:

$ config-pin P9_31 pruout

Now we just need to tell the PRU to start running that code.

# echo start > /sys/bus/platform/drivers/pru-rproc/4a334000.pru0/remoteproc/remoteproc1/state

It works. You will see your LED blink (or a square wave on your oscilloscope, in my case; 1V/div and 100ms/div is enough). The dmesg will also indicate that something is going on:

remoteproc remoteproc1: powering up 4a334000.pru0
remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 32820
remoteproc remoteproc1: remote processor 4a334000.pru0 is now up

Why is pru0 remoteproc1? Because there's another remote processor for the power management that is remoteproc0.

Note that if you know in advance that pru0 is remoteproc1, you can just use /sys/class/remoteproc/remoteproc1 for your control.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment