What is the fastest way to create parallel outputs from the PRU?

Hi all,
First of all, I am new to the BBB.
Recently, I tried to communicate the BBB to a fast DAC 12-bit which needs 20MHz sampling clock.
What I have tried is
I use PRU0_0 (P9_31) as a output clock then toggle PRU1_0 - PRU1_11 to start outputs the data in parallel (refer the method from Synchronizing Two PRUs, PRU Cookbook) but I can only get it less than 10 MHz
are there any other way/method to achieve it

Thank you in advance

If you want to benefit from full PRUSS capabilities, forget about rproc or cookbooks.

There’s no need for both PRUSS, one can do it all (perhaps one input line for trigger?). 20 MHz means 10 PRU cycles. You wont need an external clock, usually the PRU clock is sufficient (or use the PRU-IEP timer to synchronize).

Find an example at


It toogles a pin at 40 MHz (and CAP measures it). It’s easy to add further output lines and slow down the code to 20 MHz, reading data from an array in DRam/SRam.

Thank you for your reply. I haven’t found this one, will learn from this resource. Thanks again.

I had a problem on trying with
$ gcc -Wall -o pruss_toggle pruss_toggle.c -lpruio
$ ./pruss_toggle (or sudo ./pruss_toggle)
P8_11 configuration failed (pin P8_11 claimed by: ocp:P8_11_pinmux)

config-pin couldn’t fix the problem
Is this mean I need to do Custom Overlay / Universal Overlay or LKM ?

System Image : Debian Image 2018-10-07 4.14.71-ti-r80
with uEnv.txt

  • #uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-14-TI-00A0.dtbo
  • uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo
  • disable_uboot_overlay_emmc=1
  • disable_uboot_overlay_video=1

Did you comment the cape_universal enable line in /boot/uEnv.txt?


In your case libpruio tries to control P8_11, but it’s claimed by an other overlay (most likely by cape_universal, the config-pin overlay).

You also can use a workaround by skipping the claim check. Therefor manipulate the example source code by adding PRUIO_ACT_FREMUX to the constructor parameters

// our configuration is for PRU-0, so PRU-1 for libpruio, no claim checking
pruIo *io = pruio_new(act, 0, 0, 0); //    create new driver structure

In that case libpruio will override the pinmux although the CPU ball is claimed. (This may result in unexpected behaviour.)


Thank you. It is confusing about enable/disable the cape and the pin-muxing since it has been changing and cape manager is obsolete.

Disable the uboot cape universal works.


So actually we need to

  1. Enable uboot overlays

###Master Enable

  1. Disable emmc,video,rproc, and u-boot cape universal

###Disable auto loading of virtual capes (emmc/video/wireless/adc)

###pru_rproc (4.4.x-ti kernel)
###pru_rproc (4.14.x-ti kernel)

###Cape Universal Enable

  1. Enable UIO

###pru_uio (4.4.x-ti, 4.14.x-ti & mainline/bone kernel)

and we access the pins right from the application with libpruio, is this correct?

Yes, it’s confusing about the changes regarding cape manager, device trees and pinmuxing over the years. That’s why I developed the libpruio LKM solution, in order to provide pinmuxing from user application. That works on all kernel versions without adaptions.

And yes, your /boot/uEnv.txt adaptions are correct, but incomplete:

  1. The disable_uboot_overlay_XXX lines are optional; libpruio also works with enabled video, audio, emmc, …

  2. For the final installation I recommend to additionally load a custom device tree overlay that only claims the used header pins, so that the kernel knows which pins are used by the current PCB and custom application. Find details at libpruio: Pins