4

我们正在开发 Xilinx Zynq FPGA 定制 DMA 设备以快速处理大量数据。我们能够让它在裸机上运行,​​但在 Linux 中遇到了麻烦。我们在 ARM linux 内核 3.9 上工作。我们不知道如何为我们的设备实例化和使用内核驱动程序: https ://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/xilinx_axidma.c 你们有什么建议或他们可以分享一些示例代码?

现在我们计划在这里使用一些代码: http ://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt

但是我们不确定如何实例化结构设备。

4

1 回答 1

5

我认为在 xilinx_axidma.c 代码中,xdev->dev 和 chan->dev 已经初始化为 &(op->dev)。您可以将 xdev->dev 或 chan->dev 作为第一个参数传递给 DMA API。无需在 xilinx_axidma.c 中自己创建 DMA 缓冲池。总之,初始化已经正确完成。您可以继续使用 DMA API。也许您将创建一个 Tx/Rx 缓冲区环而不是一个缓冲区。由于 FPGA 芯片 DMA 控制器使用物理地址,而内核模块使用虚拟地址。因此,您必须创建某种结构来维护缓冲区环中所有缓冲区的 vaddrs 和 paddrs,例如 BD/buffer 方法。

(1) 如何分配一个 DMA 缓冲区:

  vaddr = (unsigned long) dma_alloc_coherent(xdev->dev, size, paddr, GFP_KERNEL);

返回值是分配的 DMA 缓冲区的虚拟地址,paddr 存储它的物理地址。FPGA芯片DMA控制器使用paddr,而内核模块使用vaddr。

(2) 接收到来自 FPGA 的数据后,调用以下函数使 D-Cache 无效:

  dma_unmap_single(xdev->dev, paddr, length, DMA_FROM_DEVICE);

paddr 是 DMA 缓冲区的物理地址。

(3) 在向 FPGA 发送一个缓冲区之前,调用以下函数刷新 D-cache:

  paddr = dma_map_single(xdev->dev, vaddr, length, DMA_TO_DEVICE);

paddr 是 DMA 缓冲区的物理地址, vaddr 是 DMA 缓冲区的虚拟地址。

(4) 获取接收缓冲区的物理地址:

  paddr = dma_map_single(xdev->dev, vaddr, length, DMA_FROM_DEVICE);

(5) 如何释放一个 DMA 缓冲区:

  dma_free_coherent(xdev->dev, size, vaddr, paddr);

vaddr 是 DMA 缓冲区的虚拟地址,而 paddr 是物理地址。

于 2013-07-29T02:18:32.433 回答