Reserving memory for writes to DDR from PRUs

For my application, I want to write from the PRU into a large set of circular buffers in the ARM DDR memory. Following various examples, I have gotten this to work for small amounts of data, but when I attempt to write “too much”, I crash the Linux. To me, this is not surprising, as I don’t see where the Linux has been warned to set aside the memory region where the data from the PRU will be appearing. Should I be booting with some options like “MEMMAP=” being passed in the kernel parameters? (This is a concept I’m slightly familiar with from the X86 arch). Does anyone have any successful examples of having done this? (Is MEMMAP the way to do it? Or is there perhaps something I need to add to the pruss section of the devtree?)

To add some more details, I’ve tried expanding the “extram_pool_sz” option when I modprobe in the uio_pruss driver, but get crashes way before I approach the size (which I have verified with a call to prussdrv_extmem_size()). I’ve looked at the source for the prussdrv side, and for the uio_pruss driver, and don’t see where memory is ever reserved or locked down. Also, I’ve never seen the data at the pointer returned from calling prussdrv_map_extmem, but had to mmap into /dev/mem myself (following examples I found w/ Google).

Andy S.

What you need to do. Is understand how “things” are mapped into memory. So from the gist of things, It sounds like you’re creeping into memory reserved by “something else”. NO one can tell, as you’ve not given us any code . . .

Hi Andy!

Did you check chapter 3.1.2 in the in the PruReferenceGuide? The PRUSS cannot access memory in the range of 0x0000_0000 to 0x0007_FFFF unless this feature is enabled through the PMAO register of the PRU-ICSS CFG register space.

I recommend to use the external memory for your buffer (up to 8MB), which gets allocated by the pruss_io driver. See this link (last section ERam) for details.



It sounds like you’re creeping into memory reserved by “something else”.

Reserved memory from the PRUSS point of view – haha!

Ok, as is usual, in hindsight, my error now seems massively idiotic. If you call prussdrv_map_prumem, one gets a pointer to a region of memory, whose beginning corresponds to a zero offset from the corresponding constant table entry on the PRU. So, after having gotten that to work, I decided by some magical thinking that prussdrv_map_extmem would work the same same. But no, what it actually does is give you a pointer to a buffer which the uio_pruss driver has allocated. It is then the user’s responsibility to get the physical address of this buffer, and transmit it to the PRU, and use that as the starting address for i/o into this buffer. (I’d been trying to use offsets relative to the extmem entry in the constants table, which always starts at 0x80000000 (+ offsets from writing into CTPPR_1), which was corrupting other things in the Linux memory…I guess I was hoping that the driver would somehow muscle the reserved buffer area to that address, though I now freely admit I’d have no idea how one could accomplish that, without having had the Linux VM system skip that range at boot with the MEMMAP entries…)

Ok, as is usual, in hindsight, my error now seems massively idiotic

Sounds like you learned something though ! Don’t worry however, because you’re not alone.