Strange RTEMS DMA Access on Zynq [Solved]
Avinash.Misra at jhuapl.edu
Sun Jan 13 22:02:31 UTC 2019
Thank you for your insightful email below, it went a long way towards solving my issue. I wanted to describe what I ran into here in case someone else runs into this in the future. My issue was comprised of 2 parts:
1.) Turns out I had an alignment issue with the DMA to begin with, which is why I kept getting random offsets in where my data would appear and also as to why my data would appear clipped. I'm using the AXI DMA IP and it was configured to be an "auto size" on the READ which ended up doing 64-bit transactions on a 32-bit bus. Sizing this back to 32-bit gave me what I would expect to see on the ILA in the firmware. The next thing I did was ensured my static buffer was aligned on a 32-bit address boundary this was done using the GCC align attribute to do this. Then, finally, to make sure that I wouldn't run into future alignment issues I enabled the "Allow Unaligned Transactions" option in the AXI DMA IP which, per the Xilinx Documentation, allows for and resolves unaligned address issues.
2.) The next thing that I had to do after getting the alignment issues sorted out was to ensure I was invalidating the cache. What I learned was that I had to do a rtems_cache_flush_multiple_data_lines() before starting the DMA and after the DMA had finished.
By taking the steps outlined above I am able to obtain my data from the DMA.
From: Chris Johns <chrisj at rtems.org>
Sent: Wednesday, January 9, 2019 10:36 PM
To: Misra, Avinash <Avinash.Misra at jhuapl.edu>; rtems-devel at rtems.org <devel at rtems.org>
Subject: Re: Strange RTEMS DMA Access on Zynq
On 10/1/19 2:28 pm, Misra, Avinash wrote:
> I am currently using RTEMS to access a DMA core on the Zynq and am
> noticing some interesting/peculiar behavior:
> When I provide my DMA engine a statically allocated buffer what I
> notice is that the first few bytes (5) of the buffer, after getting it
> back from the DMA, remain unchanged however the rest of the buffer
> after that contains the data (minus the first 5 bytes that are missing).
> When I provide my DMA engine a dynamically allocated buffer from
> either C++ new or Posix malloc() or posix_memalign() then I receive
> all of the data correctly from byte 0 to the last byte.
> If I provide my DMA engine my statically allocated buffer offset by
> the amount of bytes it fails to write into then I will see all of my
> data from the DMA beginning at the offset.
> Has anyone experienced something similar or have any suggestions as to
> what may be going on and/or thoughts on how to fix this behavior? I
> would ideally like to be able to do this with some statically allocated buffers.
The compiler's default alignment for the buffer will not be the same as the DMA engine. You will need to use the alignment.
What is the alignment requirement for the DMA engine? You will need to add this to the size of the static buffer and use an offset into the buffer that meets the DMA engine's alignment.
Do not forget to invalidate the cache once the DMA engine has finished.
Are you using the CDMA IP?
More information about the devel