Using PRU and GPIO


I have an application which requires use of the PRU for some fast IO. I need to use more IO than the PRU can handle, but some of the other IO only needs to operate in slow time.

Can I configure the BBB to use both PRU IO and Linux controlled GPIO.

Also could anyone point me at a tutorial for using the ADC on the BBB and can this peripheral be used in the PRU sub system?

Best Regards

Hi Andy!

The PRUSS can control the ADC subsystem. And the PRUSS can control all GPIO subsystems, so there’s no reason to control them from LINUX (host CPU). Instead control also the slow GPIOs from the PRU code.

Find example code for both, GPIO (over OCP master port = slow) and ADC in the source code of libpruio.


Yes. The PRU writes to GPIO pins are not particularly slow unless you
saturate the interconnect, but the writes are posted and happen a while
after the PRU executes them (apx. 100 nS later). Unless you need
critical timings between the direct PRU outputs and the GPIO pins, this
shouldn't be a problem.

Reads from GPIO pins are another matter. Since it is not possible to
post the reads, and the PRU (by design) doesn't execute instructions out
of order or perform speculative execution, the PRU core stalls after
issuing a read GPIO request until the data is returned from the
interconnect fabric (apx. 165 nS).

I have timing details in the comments of my PRU code for Machinekit:

Thank you for your quick replies. I will work through the examples this evening.

Ok. I think I might be getting a little confused of something called mux mode5 which looks like it is specific to an example I have been following on GPIO from Derek Molloy.

Can I create my own overlays to configure the mux which uses both GPIO and PRU IO? ( and the ADC if required)

Andy, there are two kinds of PRU GPIO writes, the direct ones, in which you write to the R30 register, and ones where you have to access the gpio subsystem, you only need to mux it to the PRU if you’re doing the direct method.

I think I have grasped it now. You can set individual pins to different mux modes?

Yes, and you can switch if you want with alternate modes using the pinmux subsystem

Check src/config/dts_custom.bas tool in the libpruio-0.2 package. With minimal configuration, it creates an individual device tree source file, compiles it and installs the binary at /lib/firmware.

But during development phase (until you found the final configuration), you may prefer an universal overlay, which provides pin-muxing capability at run-time (check src/config/dts_universal.bas).

The same happens for main core applications. When one reads a GPI-register to get the current input state value, the whole system is stalled until the read is finished. This also includes IRQs, none of them is delivered during that time. The only workaround (at least the only one I found to overcome this problem) is to set up interrupts for rising/falling edge of the inputs that have to be watched and read the input only when such an interrupt occurred.

This makes the whole system much faster comparing to plain input polling but is not a guarantee: when an input changes very fast the system is slowed down again because many interrupts happen → many reads of slow input state registers are done.