ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

VIVADO 官方AXI DMA模块 SG 模式

2021-02-07 17:30:42  阅读:882  来源: 互联网

标签:BD DMA XAxiDma int 链表 VIVADO AXI


VIVADO 官方AXI DMA模块 SG 模式

AXI DMA模块说明

AXI DMA框图

在这里插入图片描述

图一:AXI DMA 结构框图

引脚描述

在这里插入图片描述在这里插入图片描述

图二:引脚描述

补充下重点描述:

  • s_axi_lite_*:上位机通过此接口配置AXI DMA的内部寄存器。
  • m_axi_mm2s_* :上位机到DMA的写通道,传输的是上位机需要写入到外设的数据。
  • m_axi_s2mm_*:上位机到DMA的读通道,传输的是外设写入上位机的数据:即上位机从外设读取的数据。
  • m_axis_mm2s_*:DMA到外设的写通道,DMA通过此通道将上位机的数据写入外设。
  • s_axis_s2mm_*:DMA到外设的读通道,DMA通过此通道读取外设需要传给上位机的数据。
  • m_axis_mm2s_cntrl_*:DMA配置外设的控制通道(未使用)
  • s_axis_s2mm_sts_*:DMA读取外设的状态通道(未使用)
  • m_axi_sg_*:SG模式下的读写内存映射的通道

AXI DMA寄存器内存地址映射

Scatter/Gather模式

图三:SG模式下的Register Address Map

寄存器各字段详细说明看附件(AXI_DMA Preference Guide)

Scatter Gather 描述符

在这里插入图片描述

图四:SG描述符(非多通道下)

各字段详细说明看附件

SG模式下典型的系统连接结构

在这里插入图片描述

图五:SG模式下系统互联结构

SG DMA使用流程(摘取自xilinx官方教程)

MM2S 端:

  1. 在内存中开辟缓存空间,制作链表

  2. 通过 AXI4_LITE 总线将第一个 Descriptor 的地址写入 MM2S_CURDESC 寄存器

  3. 写寄存器 MM2S_DMACR.RS=1 启动 DMA,如果需要,打开 MM2S_DMACR.IOC_IrqEn 中断,结束后会发出中断

  4. 将最后一个 Descriptor 地址写入 MM2S_TAILDESC 寄存器,触发 DMA 开始通过 M_AXI_SG 总线抓取链表的 Descritptor,等 package 传输结束,读取下一个 Descriptor 信息,直到结束。

S2MM 端:

  1. 在内存中开辟缓存空间,制作链表

  2. 通过 AXI4_LITE 总线将第一个 Descriptor 的地址写入 S2MM_CURDESC 寄存器

  3. 写寄存器 S2MM_DMACR.RS=1 启动 DMA,如果需要,打开 S2MM_DMACR.IOC_IrqEn 中断,结束后会发出中断

  4. 将最后一个 Descriptor 地址写入 S2MM_TAILDESC 寄存器,触发 DMA 开始通过 M_AXI_SG 总线抓取链表的 Descritptor,等 package 传输结束,读取下一个 Descriptor 信息,直到结束。

VIVADO实际工程实现

整体系统框图

在这里插入图片描述

图六:此实验的vivado Block Design

各模块的参数设置

ZYNQ Processing System

注意:以下关于ZYNQ7 核的设置均为适配AX7015型号、不兼容的地方请自行分辨并修改

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

AXI Direct Memory Access

在这里插入图片描述

AXI4-Stream Data FIFO

在这里插入图片描述

其他

​ 适配即可

SDK工程实现

​ 使用官方SKD对AXI DMA 的SG模式的编程重点是在对于BD链表结构的理解,接下来描述vivado官方提供的DMA SDK如何实现BD链表。注:本次SDK程序是在vivado官方程序的基础上进行修改得到的。

重要的结构体

/**
 * 文件名:xaxidma.h
 * 位置:(项目位置)/(BSP文件夹)/ps7_cortexa9_0/include/xaxidma.h
 * The XAxiDma driver instance data. An instance must be allocated for each DMA
 * engine in use.
 */
typedef struct XAxiDma {
	u32 RegBase;				/* Virtual base address of DMA engine */

	int HasMm2S;				/* Has transmit channel */
	int HasS2Mm;				/* Has receive channel */
	int Initialized;			/* Driver has been initialized */
	int HasSg;

	XAxiDma_BdRing TxBdRing;     /* BD container management for TX channel */
	XAxiDma_BdRing RxBdRing[16]; /* BD container management for RX channel */
	int TxNumChannels;
	int RxNumChannels;
	int MicroDmaMode;
	int AddrWidth;		 		 /**< Address Width */
} XAxiDma;

/** 
 * 文件名:xaxidma_bdring.h
 * 位置:(项目位置)/(BSP文件夹)/ps7_cortexa9_0/include/xaxidma_bdring.h
 * Container structure for descriptor storage control. If address translation
 * is enabled, then all addresses and pointers excluding FirstBdPhysAddr are
 * expressed in terms of the virtual address.
 */
typedef struct {
	u32 ChanBase;			/**< physical base address*/

	int IsRxChannel;		/**< Is this a receive channel */
	volatile int RunState;	/**< Whether channel is running */
	int HasStsCntrlStrm; 	/**< Whether has stscntrl stream */
	int HasDRE;
	int DataWidth;
	int Addr_ext;
	u32 MaxTransferLen;

	UINTPTR FirstBdPhysAddr;/**< Physical address of 1st BD in list */
	UINTPTR FirstBdAddr;	/**< Virtual address of 1st BD in list */
	UINTPTR LastBdAddr;		/**< Virtual address of last BD in the list */
	u32 Length;				/**< Total size of ring in bytes */
	UINTPTR Separation;		/**< Number of bytes between the starting
				     address of adjacent BDs */
	XAxiDma_Bd *FreeHead;	/**< First BD in the free group */
	XAxiDma_Bd *PreHead;	/**< First BD in the pre-work group */
	XAxiDma_Bd *HwHead;		/**< First BD in the work group */
	XAxiDma_Bd *HwTail;		/**< Last BD in the work group */
	XAxiDma_Bd *PostHead;	/**< First BD in the post-work group */
	XAxiDma_Bd *BdaRestart;	/**< BD to load when channel is started */
	XAxiDma_Bd *CyclicBd;	/**< Useful for Cyclic DMA operations */
	int FreeCnt;			/**< Number of allocatable BDs in free group */
	int PreCnt;				/**< Number of BDs in pre-work group */
	int HwCnt;				/**< Number of BDs in work group */
	int PostCnt;			/**< Number of BDs in post-work group */
	int AllCnt;				/**< Total Number of BDs for channel */
	int RingIndex;			/**< Ring Index */
	int Cyclic;				/**< Check for cyclic DMA Mode */
} XAxiDma_BdRing;

/**
 * 文件名:xaxidma_bd.h
 * 位置:(项目位置)/(BSP文件夹)/ps7_cortexa9_0/include/xaxidma_bd.h
 * The XAxiDma_Bd is the type for a buffer descriptor (BD).
 */

typedef u32 XAxiDma_Bd[XAXIDMA_BD_NUM_WORDS];

​ 显而易见XAxiDma驱动实例中包含有发送 (TxBdRing) 和接收 (RxBdRing) 的 XAxiDma_BdRing 结构体,XAxiDma_BdRing 本身不是一个链表,它是一个包含BD链表基本信息和处理状态信息的结构体。由于它包含有BD链表头结点/尾节点的地址 (FirstBdAddr),因此用户可以通过 XAxiDma_BdRing 来找到和管理整个BD链表。而真正链表的组成节点是 XAxiDma_Bd 类型。这是一个有着XAXIDMA_BD_NUM_WORDS长度的u32类型的数组,而这个数组才是真正对应着实际的AXI DMA BD描述符,DMA模块通过访问这些BD描述符从内存中读取到正确的数据。

代码逻辑:

​ 控制DMA MM2S从DDR3 中读取数据,写到AXI Stream Data FIFO,再从FIFO读取出数据到DDR3,实现环通测试,使能S2MM和MM2S中断处理发送和接收逻辑。

中断设置

MM2S_DMACR Register Details

在这里插入图片描述
​ 本次实验只需要一次发送中断和一次接收中断,因此只需要需要使能IOC中断即使能MM2S_DMACR 的第12位并且同时设置其 IRQThreshold 等于BD链表的节点数量,接收中断亦然。

实现代码

​ 代码太长不方便呈现,见具体工程

对于工程下载链接 vivado_2017_版本

工程下载
ip核手册

​ 本来想设置公开的,无奈CSDN只能选择积分和粉丝。。。,关注了应该就能下载了,后续会更新其他FPGA的工程,如果想一起学习的话可以点个关注。

标签:BD,DMA,XAxiDma,int,链表,VIVADO,AXI
来源: https://blog.csdn.net/qq_44873646/article/details/113743737

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有