xilinxdmapetalinuxxilinx-edkzynq-ultrascale+

How to access Xilinx Axi DMA from Linux?


I'm a software developer but I'm a newbie to embedded software development. I have a Zynq Ultrascale board that has an Axi DMA in its Hardware and I want to access this DMA from Linux. I know I should use DMA-Engine to Access DMA in Linux and I found the following link which is the Xilinx DMA driver, but I can't add these files to my qt project without any errors and I received file(header file) not found errors. drivers/dma/xilinx/xilinx_dma.c

I have a piece of scattered information about the DMA driver, Device tree, and DMA-Engine but I know nothing about how to utilize these to access hardware DMA.

I built a Petalinux project and add DMA-Engine and DMA Test client to its kernel.

I don't know adding DMAEngine to the Petalinux project is enough or I should have a driver as well.

I don't know adding hardware specification (by .xsa file and .bit file) to the Petalinux project is enough or I should add a device tree to my Linux for detecting DMA as well

I lookup a step-by-step tutorial on how to set up Linux and qt creator for accessing DMA, or at least a clear roadmap to my target.

thank you in advance.


Solution

  • First of all, you are facing errors when adding xilinx_dma.c to the Qt project because this file is meant to be compiled as part of kernel or as a kernel module.

    Adding DMA Engine to Petalinux is not enough to work with DMA from user space. DMA Engine only provides a standardized API to let different DMAs be integrated into kernel. You need to add a client driver as well. Xilinx, as far as I know, has provided a simple client driver called DMA Proxy Driver. It also includes some simple examples that show how you can access DMA from the user space. However, if your application needs high bandwidth, you probably need to consider other options.

    There is also an open source client driver for Axi DMA which achieves higher bandwidths compared to Proxy DMA Driver. It's user space API also allows you to register a callback function to be called whenever a transaction is finished.

    The third option is to implement the driver in the user space. This can be done by defining the DMA as a UIO device in the device tree and access its register map directly from the user space. In this case, you need to allocate some contiguous memory blocks in the kernel space to avoid complications with MMU, which cannot be dealt with from the user space.