PRU-ARM data exchange

Hi guys,

What would you recommend for exchanging the data between PRU and ARM?
RPMsg?
Directly reading/writing PRU memory?
Allocating a block in the main system memory and passing its address to the PRU?

Do the recommended approaches differ depending on the data size/frequency?

Slow, massive overhead, unpredictable latency.

How do you ensure that the user-space-allocated block is continuous?

Up to 12 kB in SRam, up to 16 kB in DRam. When you need more then use ERam from uio_pruss driver.

I heard somewhere about CMEM kernel driver which can allocate contiguous memory.

I thought uio_pruss driver is phased out in favor of remoteproc approach?

I know about uio_pruss driver which can allocate contiguous memory full sure.

rproc had major changes twice a year. Will it be stable any time?

I started using RemoteProc on a project this year. I only use one PRU, PRU0.
I have to classify myself as an intermediate developer on the BeagleBone platform and the same for Linux. I’m getting back into C after many, many years of not using it.
So, my experience may have been more difficult than others.

To your question, I was able to set up Remoteproc so the ARM code sent a command to the PRU that started a loop that read three of the ADC channels and sent the data back to the ARM using Remoteproc. The ARM then formatting the data and saved it in CSV format.

It was definitely tricky to get working. Payload formatting is critical or else you’ll get partial messages back or miss messages. I also found that the PRU can send many messages faster than the ARM can process them so I actually put a delay in on the PRU side after each record was sent back to the ARM. My read cycle time was about 22ms but could have been faster I believe. I really don’t know how fast the ARM can receive the data from the PRU. It can probably be calculated or estimated but this met our needs so we didn’t dig into that any further.

I highly recommend Mark Yoder’s PRU Cookbook and going through everything TI has on their sites about the PRU and Remoteproc.

This is not for the timid or faint of heart.

Now, that said, we have had trouble getting the PRU to recognize a message from the ARM after it has received the first message to start its routine. We’ve not been able to figure out why but it seems like the interrupt bit that gets set when the ARM sends a message is not being recognized by the PRU.

Also, not being able to print output from the PRU side without a UART connection is a pain for debugging PRU code. We use LEDs connected to GPIO lines to indicate where we are in the code for debugging sometimes. This is really terrible.

FPP requires being able to send a relatively large memory block (300K or more) from ARM to PRU 20-40 times per second. We use rproc to setup the PRU’s but to solve the memory transfer, we ended up going with a device tree overlay to reserve a large (2MB) block of memory at a specific location. We can mmap that into the arm process and the PRU programs know right where it is. By going larger, we can do a kind of double buffering where the PRU is using one block while the arm is preparing the next.

Possibly not “ideal”, but it works well:

DTS: fpp/bbb-fpp-reserve-memory.dts at master · FalconChristmas/fpp · GitHub

1 Like

Daniel,

Thanks for adding to this post! We have been using RPMSG ok for nearly 6 months now but using it for debugging is really awful. I have zero experience with device tree overlays. Since starting to work with the BBB I have tried to go with ‘off the shelf’ drivers, kernels, etc. and focused mostly on the application C code.

So, with that said, if you have time, could you share how I go about deploying / integrating the device tree overlay you’ve shared onto our Beagle and integrate that into our C code? I realize it’s asking a lot but I could learn a lot from this if you could share it!

Walter