
思路是这样,也是米尔科技demo的思路,首先PS通过AXI-lite配置DMA的工作模式,然后,PS将数据写入DDR,再然后,PS控制DMA读出之前写入的数据,将数据流写入FIFO(读完后DMA会向PS发送中断),再然后,PS控制DMA将FIFO的数据流再通过AXI总线写回DDR(写完后DMA会向PS发送中断),PS判断写入的数据和读出的数据是否一致,完成实验。

在讨论Zynq DMA的设计细节之前,让我们先要解释几个DMA控制器的原则:
典型的DMA控制器可以工作在以下三种模式:
1.突发模式-以一个连续的操作方式来传输一个完整的数据包,在许多应用中,DMA的突发模式传输会拒绝处理器的总线访问,对于不同的系统而言,这有利有弊(可以是件好事,也可能是一件非常糟糕的事情。)
2. 周期挪用模式-跟处理器一起交替完成单独的DMA字节或者字传输的总线访问,这种模式可以防止处理器无法访问总线。
3.透明模式-效率最高的传输模式,只有在处理器在执行任务而不需要访问外部系统总线的时候,DMA才能传输数据。
DMA控制器支持scatter/gather操作,这是一个非常有用的特性,这个特性允许多个数据源的数据传输到同一个目的地址,或者同一个源地址的数据传输到不同的目的地址(也可以称为“buffers”)
Zyng SoC是基于ARM内核的处理系统,它有一个DMA控制器,该DMA控制器连接在Zynq的AXI4中央互连架构上,通过AXI总线来传输数据,它在系统 存储器和Zynq的可编程逻辑单元(PL)之间完成64位的AXI总线传输。如下图所示,Zynq DMA有8个通道,可以同时执行8个DMA传输操作。
DMA控制器具有以下的特点:
* 8个独立的通道,4个可用于PL—PS间数据管理,每个通道有1024Byte的MFIFO;
* 使用CPU_2x 时钟搬运数据,CPU_2x = (CPU frq/6)*2;
* 执行自定义内存区域内的DMA指令运行DMA;
* AHB控制寄存器支持安全和非安全模式;
* 每个通道内置4字Cache;
*可以访问SoC的以下映射物理地址:DDR、OCM、PL、Linear QSPI Read、SMC和M_AXI_GP设备,访问设备的互联结构如下图所示:

之前跳过搭建工程环节,我们来看看这次需要添加哪些IP,如下图

有点模糊,我一个个截图出来,这样可以放大了看清楚,包含了zynq内核,DMA模块,中断,FIFO,内部链等,如下图:

接下来生成顶层文件,启动SDK,把demo代码copy进去,最后编译,生成镜像文件,通过SD卡烧录到办卡里面,先把硬件连接好:

看下实现的函数,如果输入输出数据一致就会打印:Successfully ran AXI DMA SG Polling Example
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr){ XAxiDma_BdRing *TxRingPtr; XAxiDma_BdRing *RxRingPtr; XAxiDma_Bd *BdPtr; int ProcessedBdCount; int FreeBdCount; int Status; TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr); RxRingPtr = XAxiDma_GetRxRing(AxiDmaInstPtr); /* Wait until the one BD TX transaction is done */ while ((ProcessedBdCount = XAxiDma_BdRingFromHw(TxRingPtr, XAXIDMA_ALL_BDS, &BdPtr)) == 0) { } /* Free all processed TX BDs for future transmission */ Status = XAxiDma_BdRingFree(TxRingPtr, ProcessedBdCount, BdPtr); if (Status != XST_SUCCESS) { xil_printf("Failed to free %d tx BDs %d\r\n", ProcessedBdCount, Status); return XST_FAILURE; } /* Wait until the data has been received by the Rx channel */ while ((ProcessedBdCount = XAxiDma_BdRingFromHw(RxRingPtr, XAXIDMA_ALL_BDS, &BdPtr)) == 0) { } /* Check received data */ if (CheckData() != XST_SUCCESS) { return XST_FAILURE; } /* Free all processed RX BDs for future transmission */ Status = XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr); if (Status != XST_SUCCESS) { xil_printf("Failed to free %d rx BDs %d\r\n", ProcessedBdCount, Status); return XST_FAILURE; } /* Return processed BDs to RX channel so we are ready to receive new * packets: * - Allocate all free RX BDs * - Pass the BDs to RX channel */ FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr); Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr); if (Status != XST_SUCCESS) { xil_printf("bd alloc failed\r\n"); return XST_FAILURE; } Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount, BdPtr); if (Status != XST_SUCCESS) { xil_printf("Submit %d rx BDs failed %d\r\n", FreeBdCount, Status); return XST_FAILURE; } return XST_SUCCESS; }
复制代码
附上源代码哟:

2019-12-1 16:55 上传
点击文件名下载附件

2019-12-1 16:55 上传
点击文件名下载附件

2019-12-1 16:53 上传
点击文件名下载附件

2019-12-1 16:51 上传
点击文件名下载附件

2019-12-1 16:50 上传
点击文件名下载附件

2019-12-1 16:59 上传
点击文件名下载附件
***************************************完美分割线***************************************
【MYD-C7Z010/20开发板 试用体验】惊鸿一瞥,便爱上!
【MYD-C7Z010/20开发板 试用体验】核心板以及底板资源介绍
【MYD-C7Z010/20开发板 试用体验】上电问声好,hello world工程搭建实现
【MYD-C7Z010/20开发板 试用体验】PL外部中断PS实验
【MYD-C7Z010/20开发板 试用体验】HDMI(不使用IP)简单color bars 实验
MYD-C7Z010/20购买链接
继续阅读本篇相关更多标签
全部回复 2
- 0 主题
- 1711 帖子
- 6181 积分
身份:LV6 初级工程师
E币:2176
发消息
yzw92


发表于2019-12-2 06:55:05
显示全部楼层
沙发
一如既往的支持!
>>资料:从零开始,ubuntu上 搭建xilinx zynq linux 编译环境
- 支持
- 反对
- 举报
回复
yzw92 发表于 2019-12-2 06:55
一如既往的支持!
多谢多谢

评测文章
热帖
大家都在看的技术资料
举报
内容系网友发布,其中涉及到安全隐患的内容系网友个人行为,不代表面包板社区观点
关闭
站长推荐
/3


-
返回顶部
-
工具栏