一、AXI DMA概述
AXI DMA是指Advanced eXtensible Interface Direct Memory Access,是Xilinx公司提供的基於AMBA協議的DMA核,用於處理高速數據傳輸,可以在FPGA內的不同IP核之間以及外部設備與FPGA之間進行數據傳輸。
AXI DMA支持以下特性:
- 高吞吐量的數據傳輸
- 支持多通道並發傳輸
- 支持內存映射和文件操作等高級特性
- 集成了CDO(Completion determined Operation),支持數據傳輸的補償機制
二、AXI DMA SG
字面意義上,SG是指Scatter-Gather,一種數據傳輸的方式,也就是將數據在內存中分為若干幀,每幀數據可能存儲在不同的物理地址中,傳輸時AXI DMA可以根據事先的描述從內存中逐個取出幀數據存到寄存器中進行發送,優點是可以降低在地址映射和DMA中間數據複製的開銷以提升系統性能。以下是AXI DMA SG的使用示例:
<!-- AXI DMA SG示例 -->
<axidma_sg id="dma_sg">
<-- AXI DMA配置 -->
<register name="CONFIG" offset="0x00" value="0x00"/>
<-- 內存地址1 -->
<register name="SG_CTL" offset="0x00" value="0x80000000"/>
<register name="SRC_ADDR_1" offset="0x04" value="0x10000000"/>
<register name="DST_ADDR_1" offset="0x08" value="0x20000000"/>
<register name="LENGTH_1" offset="0x0c" value="0x100"/>
<-- 內存地址2 -->
<register name="SG_CTL" offset="0x10" value="0x80000000"/>
<register name="SRC_ADDR_2" offset="0x14" value="0x11000000"/>
<register name="DST_ADDR_2" offset="0x18" value="0x21000000"/>
<register name="LENGTH_2" offset="0x1c" value="0x200"/>
</axidma_sg>
三、AXI DMA單向傳輸
AXI DMA支持單向數據傳輸,單向傳輸可以在數據方向鎖定時消除請求延遲,提高傳輸效率。例如,以下代碼示例演示了使用AXI DMA進行單項傳輸:
<!-- AXI DMA單項傳輸示例 -->
<axidma id="dma">
<-- AXI DMA配置 -->
<register name="CONFIG" offset="0x00" value="0x00"/>
<register name="SRC_ADDR" offset="0x18" value="0x10000000"/>
<register name="DST_ADDR" offset="0x20" value="0x20000000"/>
<register name="LENGTH" offset="0x28" value="0x400"/>
</axidma>
四、AXI DMA驅動
AXI DMA可以很方便地在Linux系統中使用,只要安裝了相關的驅動程序即可,以下是在Linux系統中使用AXI DMA的驅動程序示例:
/* AXI DMA驅動示例 */
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/of_device.h>
static struct dma_chan *dma_tx_ch; // DMA通道
static dma_addr_t dma_tx_addr; // DMA內存映射的物理地址
static int dma_init(void)
{
struct device_node *np = NULL;
struct scatterlist sg_tx;
struct dma_async_tx_descriptor *dma_tx_desc;
np = of_find_compatible_node(NULL, NULL, "xlnx,axi-dma");
if (!np) {
pr_err("Failed to find DMA node\n");
return -EINVAL;
}
dma_tx_ch = dma_request_chan(&(np->dev), "dma0");
if (IS_ERR(dma_tx_ch)) {
pr_err("DMA channel request failed\n");
return -EFAULT;
}
/* 申請DMA內存 */
dma_tx_addr = dma_map_single(&(np->dev), &dma_tx_buf, DMA_LEN, DMA_TO_DEVICE);
sg_init_one(&sg_tx, dma_tx_addr, DMA_LEN);
dma_tx_desc = dmaengine_prep_dma_memcpy(dma_tx_ch, dma_tx_addr, DMA_BUF_ADDR, DMA_LEN, DMA_PREP_INTERRUPT);
if (!dma_tx_desc) {
pr_err("DMA prep memcpy fail\n");
return -EINVAL;
}
dma_submit_error dma_async_submit(dma_tx_desc);
return 0;
}
static void dma_exit(void)
{
dmaengine_terminate_all(dma_tx_ch);
dma_unmap_single(&dev, dma_tx_addr, DMA_LEN, DMA_TO_DEVICE);
dma_release_channel(dma_tx_ch);
}
module_init(dma_init);
module_exit(dma_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Xilinx Inc.");
五、AXI DMA SG BD
AXI DMA支持的另一個特性是SG BD模式。BD是指Buffer Descriptor,即緩衝區描述表。它基於SG模式,將傳輸參數和每個SG段所使用的緩衝區的物理地址以及傳輸完成後的信號等參數描述到BD表中,從而更好地管理傳輸。以下是AXI DMA SG BD的使用示例:
<!-- AXI DMA SG BD示例 -->
<axidma_sg_bd id="dma_sg_bd">
<register name="CONFIG" offset="0x00" value="0x01"/>
<-- BD號0 -->
<register name="BD_ADDR_0" offset="0x00" value="0x50000000"/>
<register name="BD_LENGTH_0" offset="0x04" value="0x400"/>
<register name="BD_COMPLETED_0" offset="0x08" value="0x01"/>
<-- BD號1 -->
<register name="BD_ADDR_1" offset="0x10" value="0x51000000"/>
<register name="BD_LENGTH_1" offset="0x14" value="0x800"/>
<register name="BD_COMPLETED_1" offset="0x18" value="0x00"/>
</axidma_sg_bd>
六、AXI DMA丟數據
在使用AXI DMA進行數據傳輸時,可能會由於各種原因導致數據丟失問題,這是非常常見的問題之一。下面提供幾個丟失數據的原因和解決辦法。
原因1:鏈路層丟包引起的數據丟失
解決方案:
- 調整DMA傳輸速度以適應鏈路層速度
- 優化DMA傳輸的協議
- 加入FIFO等緩存進行中轉
原因2:由於FIFO的填充導致數據丟失
解決方案:
- 調整FIFO的大小以適應數據量的多少
- 增大FIFO的讀寫速度或者增加多個FIFO,讓數據同時進行寫入和輸出
七、AXI DMA循環傳輸
AXI DMA支持循環傳輸,即在數據傳輸完成後再返回之前的地址繼續傳輸,這樣可以實現循環使用內存和控制器,提高系統效率。以下是AXI DMA循環傳輸的使用示例:
<!-- AXI DMA循環傳輸示例 -->
<axidma_cyclic id="dma_cyclic">
<-- AXI DMA配置 -->
<register name="CONFIG" offset="0x00" value="0x02"/>
<register name="SRC_ADDR" offset="0x04" value="0x10000000"/>
<register name="DST_ADDR" offset="0x08" value="0x20000000"/>
<register name="LENGTH" offset="0x0c" value="0x400"/>
</axidma_cyclic>
原創文章,作者:WULBO,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/373182.html