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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
WULBOWULBO
上一篇 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

发表回复

登录后才能评论