This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM335X: DDR to PRU SRAM EDMA transfer on AM335X

Part Number: PROCESSOR-SDK-AM335X

Hello,

I was trying to find an example of a simple example of data transfer from DDR to PRU SRAM using EDMA which will be triggered by the PRU, the only example I've seen was this post below:

e2e.ti.com/support/processors/f/791/t/149738?DMA-from-PRU-to-DDR-RAM-under-Linux which points to PRU_edmaConfig (accessing the EDMA without precautions as per that example crashes the system)

Some interesting work was also done here:

github.com/.../beaglebone-pru-dma

both of which are based on PRU_SW project that was discontinued. This is the environment we're using:

- Linux-rt 4.19

- ARM-PRU communication using remoteproc

- Goal: ARM will allocate a buffer in DDR, passes the details (address, size) to the PRU with RPMsg, then PRU to initiate EDMA transfer.

Please let us know what is the best approach to achieve this.

Thank you.

  • Hello Mehdi,

    Please tell us a bit about your use case. What is the PRU doing? Is the RPMsg a one-time setup message, or intended to be sent every time a data transfer is going to take place? Are you targeting a particular throughput or latency for the data transfer?

    Regards,

    Nick

  • Hello Nick,

    We'll be using these 2 messaging:

    - ARM to PRU RPmsg: Initial setup as described above to pass pointer to buffer(s) and size of buffer. This is a one-time setup.

    - PRU to ARM: at regular intervals to inform ARM to update data in buffer.

    The idea is to have the ARM filling up large ping-pong buffers (worth of 10ms), PRU will trigger DMA to copy 1ms (4kB) worth of data to its internal SRAM (ping-pong as well, one being used to write data to DAC (parallel DAC), the other being refilled by DMA). Once the 10ms ping buffer used, PRU messages the ARM to refresh that buffer while starting to use the pong.

    As you see from above the latency on the PRU side will need to stay well below 1ms to avoid buffer underrun and well below 10ms on the ARM side.

    For the edma, the source address would be 0x8xxxxxxx (DDR buffer address) and destination 0x4a310000/0x4a320000 (PRU shared SRAM).

    Is there a simple way to use the edma from the PRU side, ex: reserve some dma resources for PRU usage and have PRU access dma directly in a similar way to the PRU_edmaConfig example? or you think the only way is to write a kernel module to avoid conflicts?

    Thank you.

  • Hello Mehdi,

    What is the PRU doing with the data? will both PRU cores be used? If one of the PRU cores is unused, you could probably dedicate that core to moving data between PRU DRAM and DDR. That would probably be easier than trying to get the DMA involved.

    For an example of a similar setup, take a look at Flexible Interface Reference Design for Simultaneous, Coherent DAQ Using Multiple ADCs. Code is in your Linux Processor SDK under example-applications/pru-adc-x.x. In that example, the Interface PRU core does all the work of implementing SPI and interacting with the external ADCs, while the Controller PRU core takes the input data and places it in a ping-pong buffer for the ARM.

    FYI, RPMsg is fine as a simple to use messaging system. However, it does have nondeterministic latency - round trip latencies of 1ms are common on AM335x. So you will want to use a different messaging method if lower, more deterministic latencies are required.

    Regards,

    Nick

  • Hello Nick,

    The PRU is writing data to R30 (parallel DAC), avoiding access to DDR mitigates jitter vs. using low latency PRU RAM. Indeed as you expected, the other PRU is busy with other tasks. I thought it is natural to use DMA for data movement but was surprised not to find relevant examples.

    You are absolutely correct about RPMsg, for now I don't see the reason for going with IRQ and associated complexity as we are using large enough buffers to mask jitter's effects (not only from RPmsg but also other high priority kernel tasks).

    Thank you for the example, I was aware that using the other PRU for data transfer was an option but not in our case.

    Regards,

    Mehdi

  • Hello Mehdi,

    Got it. Just to double check, are you using the PRU_edmaConfig project in your Linux SDK under example-applications/pru-icss-x.x.x/examples/am335x? (I have not yet run it myself, but I would expect that it was at least tested on AM335x, and I am not sure what differences exist between the AM18x and the AM335x code). If you are still running into issues running the unmodified example, please attach the error outputs.

    Regards,

    Nick

  • Hello Nick,

    Got it to work, I think it's important to note for anyone that might come across this post that to avoid conflicts with Linux it's best to reserve a dma PaRAM and a dma channel in the dts:

    1- ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by the driver

    2- dma-channel-mask: Mask of usable channels. Single uint32 for EDMA with 32 channels, array of two uint32 for EDMA with 64 channels.

    Thank you for your support.

    Mehdi

  • Hello Mehdi,

    Thank you for posting your solution! That is a really good point for future customers. Each resource in the processor should only have one processor core controlling it. For peripherals like ADC, that means that the ADC driver should be disabled in Linux if the PRU is controlling the ADC. Based on your experiments, for DMA you need to disable based on PaRAM and channel.

    Regards,

    Nick