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?
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?
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.
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.
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.
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).
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."