PRU Communications: Beaglebone Black

We are a group working with a Beaglebone and trying to get more time determinism between the PRUs. We are trying to get one PRU to respond to a trigger from the other PRU. The INTC framework seems quite complex, and we are finding it quite difficult to decipher or understand (but an example might help us build on it). Does the PRU allow for a timed response like an interrupt based mechanism? Can someone suggest something for our requirement of communication between the PRUs?

Thank you,

-Vadde

The PRUs do not support a traditional interrupt mechanism where code flow is diverted due to an event. You must poll a flag to determine if the interrupt has occurred. The PRUs latency in response will be dependent upon how often you poll. I suggest you keep your main loop short and use state machines for all operations so that a poll is not delayed by a long function.

You may need to add an additional processor if you need traditional interrupt operation.

Thank you for the suggestion. We will explore this option. Do you think the
shared memory between PRUs is a natural choice of location to consider
placing such a mailbox at?

This is from the TI FAQ on the PRU:

Does the PRU-ICSS/ PRU_ICSSG Support Interrupts?

Yes,but not in the same way that most cores support interrupts.The PRU-ICSS/ PRU_ICSSG contains an interrupt controller that can map 64 system events down to two flags that are set in a PRU core register (bits 30 and 31 in core register R31).The PRU core can then check each of these flags in a single cycle to see if an event has occurred.These flags can either be polled upon or checked periodically (dependent on what makes the most sense for the use case).The PRU-ICSS/ PRU_ICSSG interrupt controller does not support jumping the program counter of the PRU core to a pre-determined function when an event occurs.

The other PRU can be one of these 64 events that sets a bit. Whether it makes more sense to use the bits in R31 or shared memory will depend upon your application. Shared memory would allow you to queue up more data than just a single bit, but a larger message could take more time to process. This is a design decision you will have to make.

AFAIK only the uio_pruss driver supports interrupts. But that doesn’t make sense. Polling a certain memory adress is more effective.

Use any memory area with direct (no OCP latency) PRU access: DRAM-[0|1] or SRAM

But note, there’re acces rules: when one PRU allways polls a memory address, the other may not be able to change the value.

Regards

Thank you, Paul. We will try using the PRU core register and see what
performance we can get. The shared memory option sounds less useful, but we
might try it just to find out how limited it is. The upside of the shared
memory is the relative ease of use, but that is not good enough if it leads
to memory contention issues.

Regards.

Thanks, TJF. Any PRU documentation on the access rules and how to avoid a
memory contention?

Find details in

https://elinux.org/images/d/da/Am335xPruReferenceGuide.pdf

In the DRAM each PRU has prefered access to its own area (chapter 3.1.2). So the DRAM of the triggering PRU may be a better choise for the shared memory.

Regards

Thanks much. We are going to use this as a standby and try using the PRU
core register flag setting as a default option.

Yes, that’s a further option. You can HALT one PRU and restart it by setting bit 1 (ENABLE) in the CONTROL register, using the other PRU.

But note, you also have to increase the STATUS register, in order to jump over the HALT statement.

Regards

As has been discussed, the PRUs have no direct "interrupt" like
functionality that interrupts and redirects program execution.

In addition to the various methods already discussed, if you are
trying to tightly couple program execution between the two PRU cores,
I suggest using the transfer instructions (XIN/XOUT). While these
instructions are typically used to access the scratchpad and hardware
multiplier, you can also specify a direct connection between the two
PRU cores. In this case, one PRU core executes an XIN instruction and
the other core executes an XOUT. The core that executes the
instruction first will stall until the other PRU executes it's
transfer instruction, at which point the two PRU cores will continue
executing code, synchronized by the transfer instruction. The
transfer is terminated if either PRU core stalls for more than 1024
cycles.

Details are in the TRM, but you have to have one of the versions with
full details on the PRU cores (eg: spruh73c or similar).

Sounds a tad more intricate, but seems powerful. Thanks for letting us know, Steinkuehler.

Interesting, thanks Charles!

From the TRM:
"In direct connect mode (device ID 14), any PRU transaction will be
terminated if the stall is greater than 1024 cycles. This will
generate the event pr<1/0>_xfr_timeout that is connected to INTC."

Thanks for quoting the TRM for me (I didn’t download the ‘c’ version yet).