一、引言
ZynqMP SOC是xilinx公司推出的面向AI应用(如:云计算、边缘计算)、高度灵活、高性能的处理器系列,我们选择它作为产品的处理器平台,以保证未来的可持续演进。本文简要说明在基于Zynq MPSOC的产品开发中,如何在Linux的用户面实现AXI DMA传输。
Linux内核提供了dma的驱动框架,为在内核空间添加不同的dma驱动提供了标准的API接口,该框架支持多种形式的dma传输,如:内存与内存之间的axi-cdma,内存到设备或者设备到内存的axi-dma等。
二、用户面dma传输的实现
Xilinx则针对自己的SOC芯片,基于Linux dma驱动框架的基础上,提供了多种dma驱动引擎,允许用户在内核空间编写特定的dma驱动代码。但是,上述无论是linux的 dma框架,还是xilinx的dma驱动引擎,都没有提供用户面的接口,也就是说,要在用户空间使用dma,还需要另外编写代码来实现。
Xilinx的FPGA的dma-ip在linux内核中的驱动代码在文件drivers/dma/xilinx/xilinx-dma.c中,添加的user plane代码包括了一系列函数以及新增的数据结构,这部分代码在xilinx-dma.c文件中实现。几个要点:
1、dma缓冲区采用ping-pang buffer,缓冲区在内核驱动中予以分配,在驱动代码中提供了mmap接口,在user plane中程序可以访问该缓冲区,不需要进行数据从内核空间到用户空间的拷贝;
2、user plane程序通过ioctl()来启动dma、获取dma的数据;
3、在我们的应用中,dma数据传输是单方向的,即:从fpga到A53,且每一次dma传输的数据帧很大,约600K+ bytes;
4、在fpga中使用了2个axi-dma IP,连接到MPSOC的HPC口,在linux的设备树中,配置了2路axi-dma;
相关的代码片段如下:
/**
* Map the dma memory into user space
*/
static int zynqmp_axidma_mmap(struct file *file_p, struct vm_area_struct *vma)
{
struct xilinx_dma_device *pchannel_p;
pchannel_p = (struct xilinx_dma_device *)file_p->private_data;
return dma_mmap_coherent(pchannel_p->dev, vma,
pchannel_p->interface_p, pchannel_p->interface_phys_addr,
vma->vm_end - vma->vm_start);
}
/**
* Open the device file
*/
static int zynqmp_axidma_open(struct inode *inode, struct file *file)
{
/* get the address of 'zynqmp_dma_device' structure */
file->private_data = container_of(inode->i_cdev, struct xilinx_dma_device, cdev);
return 0;
}
/**
* Close the file
*/
static i