Some background info about my problem:

  • I have an external device that is constantly giving me data through SPI
  • I handle SPI reads with DMA from userspace, as kernel based solutions (already implemented and my own driver) turned out to have too much latency sometimes - see this question
  • the data format is: one byte "header" that indicates presence of data, and - if header is non-zero - 256 byte data chunk follows
  • if header byte turns out to be 0, there is no data chunk whatsoever, and I need to check following byte, if it is also 0, then the next one, etc, until I find non-zero byte - then I know I have 256 bytes of data following
  • I receive data from my SPI device into one of several buffers (for now it's two), when I finish writing to one buffer then I start filling next one, after the last one is filled I'm going back to the first
  • to further process my data and separate useful bytes from header bytes, I need to copy 256 bytes data chunks from device buffer into some separate buffer (processing data in the same input buffer would be risky, as I may not keep up with processing the data and end up with it being overwritten)

First thing I tried was simple CPU-side copying, and it works, but uses relatively lot of CPU time. I was thinking about using DMA for that, but I have a few worries:

  1. Although target address data could always be nicely aligned to 256 bytes, the same couldn't be said about source addresses, which - because of header bytes - would not allow start of every data part of consecutive batch to be power-of-two aligned (in fact, very few such data batches would be nicely aligned at all). In BCM2835 ARM Peripheral documentation it is stated that:

The DMA can deal with byte aligned transfers and will minimise bus traffic by buffering and packing misaligned accesses

but I'm not sure if this means that source and/or destination address might not be aligned to some power of two amount of bytes.

  1. I'm also not sure how to interpret SRC_WIDTH and DEST_WIDTH in DMA Transfer Information. Looks like I can choose either 4 or 16 bytes to be read / written at once? But why set it up separately for source and destination? I mean, if I do, for example, 128 bit reads, can I do 32-bit writes? Does it make any sense? And most importantly, should I go for higher read/write widths, or does it not impact performance?

  2. In DMA Transfer Information I can also set something called BURST_LENGTH. This is something I don't quite understand, because burst is said not to be working in all scenarios? And that setting up too many burst bytes may stack and effectively stall consecutive memory transfer operations? So how should I set burst so that I can achieve best performance without it backfiring in any way?

  3. DMA transfers require source and target memory to be given as bus addresses. As I understand, there are two ways of achieving this:

  • to allocate some memory on GPU through VC Mailbox and retrieve physical and bus addresses from it
  • or to find out how particular part of virtual memory maps to physical one, and retrieve bus address from physical

But it looks like first approach is generally more advised because in this way I can obtain non-cached memory. It seems like cached memory is not very DMA friendly, but is it, really? I mean - in my scenario, I would first copy my data from one buffer to another, and only then access output buffer on CPU side, so it not being cached at the time would not be a big deal, would it?

I'd be grateful for any tips and information, I'm not that experienced with using RPI's DMA engine.

  • You might want to indicate the context here, presumably it is linux kernel/driver programming... note that it probably isn't pi specific and you might be better off trying on SO: stackoverflow.com/questions/tagged/linux+dma
    – goldilocks
    Mar 25, 2023 at 19:49
  • Actually it's userspace programming, and I guess it's rather specific to RPI itself - unless these things I mentioned are common for DMA in general, which I don't know.
    – PookyFan
    Mar 25, 2023 at 19:57
  • 1
    DMA will not discard header bytes. It just copies x bytes from an address to an address. I see no point in using DMA for this (unspecified) task.
    – joan
    Mar 25, 2023 at 20:06
  • The big idea was to set up a few transfers, or maybe even chain of transfers to improve performance of copying these bytes. Of course DMA itself won't discard header bytes, I'd need to specify source addresses myself (which is one of my main concern, if it's going to work while source address is not power-of-two aligned).
    – PookyFan
    Mar 25, 2023 at 20:14
  • I sense a strong probability of an XY problem here, as joan hints perhaps you are hung-up on the concept of "DMA" and the goal of physical alignment, and you are abstracting too much by not relating this back to the concrete context....
    – goldilocks
    Mar 25, 2023 at 22:07


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.