我认为在 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 是物理地址。