AXI DMA的詳細闡述

一、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-hant/n/373182.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
WULBO的頭像WULBO
上一篇 2025-04-25 15:26
下一篇 2025-04-25 15:26

相關推薦

  • index.html怎麼打開 – 詳細解析

    一、index.html怎麼打開看 1、如果你已經擁有了index.html文件,那麼你可以直接使用任何一個現代瀏覽器打開index.html文件,比如Google Chrome、…

    編程 2025-04-25
  • Resetful API的詳細闡述

    一、Resetful API簡介 Resetful(REpresentational State Transfer)是一種基於HTTP協議的Web API設計風格,它是一種輕量級的…

    編程 2025-04-25
  • 關鍵路徑的詳細闡述

    關鍵路徑是項目管理中非常重要的一個概念,它通常指的是項目中最長的一條路徑,它決定了整個項目的完成時間。在這篇文章中,我們將從多個方面對關鍵路徑做詳細的闡述。 一、概念 關鍵路徑是指…

    編程 2025-04-25
  • neo4j菜鳥教程詳細闡述

    一、neo4j介紹 neo4j是一種圖形數據庫,以實現高效的圖操作為設計目標。neo4j使用圖形模型來存儲數據,數據的表述方式類似於實際世界中的網絡。neo4j具有高效的讀和寫操作…

    編程 2025-04-25
  • c++ explicit的詳細闡述

    一、explicit的作用 在C++中,explicit關鍵字可以在構造函數聲明前加上,防止編譯器進行自動類型轉換,強制要求調用者必須強制類型轉換才能調用該函數,避免了將一個參數類…

    編程 2025-04-25
  • HTMLButton屬性及其詳細闡述

    一、button屬性介紹 button屬性是HTML5新增的屬性,表示指定文本框擁有可供點擊的按鈕。該屬性包括以下幾個取值: 按鈕文本 提交 重置 其中,type屬性表示按鈕類型,…

    編程 2025-04-25
  • crontab測試的詳細闡述

    一、crontab的概念 1、crontab是什麼:crontab是linux操作系統中實現定時任務的程序,它能夠定時執行與系統預設時間相符的指定任務。 2、crontab的使用場…

    編程 2025-04-25
  • Vim使用教程詳細指南

    一、Vim使用教程 Vim是一個高度可定製的文本編輯器,可以在Linux,Mac和Windows等不同的平台上運行。它具有快速移動,複製,粘貼,查找和替換等強大功能,尤其在面對大型…

    編程 2025-04-25
  • forof遍歷對象的詳細闡述

    forof是一種ES6的語法糖,用於遍歷可迭代對象。相較於傳統的for循環和forEach方法,forof更加簡潔、易讀,並且可以遍歷各種類型的數據。 一、基本語法 forof的基…

    編程 2025-04-25
  • 網站測試工具的詳細闡述

    一、測試工具的概述 在軟件開發的過程中,測試工具是一個非常重要的環節。測試工具可以快速、有效地檢測軟件中的缺陷,提高軟件的質量和穩定性。與此同時,測試工具還可以提高軟件開發的效率,…

    編程 2025-04-25

發表回復

登錄後才能評論