当前位置: 首页 > news >正文

成都sw网站建设内容营销平台

成都sw网站建设,内容营销平台,申请做网站要什么局,网销培训1#xff09;实验平台#xff1a;正点原子MPSoC开发板 2#xff09;平台购买地址#xff1a;https://detail.tmall.com/item.htm?id692450874670 3#xff09;全套实验源码手册视频下载地址#xff1a; http://www.openedv.com/thread-340252-1-1.html 第二十一章AXI D…1实验平台正点原子MPSoC开发板 2平台购买地址https://detail.tmall.com/item.htm?id692450874670 3全套实验源码手册视频下载地址 http://www.openedv.com/thread-340252-1-1.html 第二十一章AXI DMA环路测试 DMA(Direct Memory Access直接存储器访问)是计算机科学中的一种内存访问技术。它允许某些计算机内部的硬件子系统可以独立地直接读写系统内存而不需中央处理器CPU介入处理。DMA是一种快速的数据传送方式通常用来传送数据量较多的数据块很多硬件系统会使用DMA包括硬盘控制器、绘图显卡、网卡和声卡在使用高速AD/DA时使用DMA也是不错的选择。 本章我们使用PL的AXI DMA IP核实现DMA环路功能了解DMA的使用。本章包括以下几个部分 2121.1简介 21.2实验任务 21.3硬件设计 21.4软件设计 21.5下载验证 21.1简介 DMA是所有现代计算机的重要特色它允许不同速度的硬件设备进行沟通而不需要依于中央处理器的大量中断负载。否则中央处理器需要从来源把每一片段的数据复制到寄存器然后把它们再次写回到新的地方。在这个时间里中央处理器就无法执行其它的任务。 DMA是用硬件实现存储器与存储器之间或存储器与I/O设备之间直接进行高速数据传输。使用DMA时CPU向DMA控制器发出一个存储传输请求这样当DMA控制器在传输的时候CPU执行其它操作传输操作完成时DMA以中断的方式通知CPU。 为了发起传输事务DMA控制器必须得到以下数据 • 源地址 — 数据被读出的地址 • 目的地址 — 数据被写入的地址 • 传输长度 — 应被传输的字节数 图 21.1.1 DMA存储传输过程 DMA存储传输的过程如下 为了配置用DMA传输数据到存储器处理器发出一条DMA命令。DMA控制器把数据从外设传输到存储器或从存储器到存储器而让CPU腾出手来做其它操作。数据传输完成后向CPU发出一个中断来通知它DMA传输可以关闭了。 MPSOC中有两个通用DMA控制器LPD DMA和FPD DMA。除了一致性命令缓冲区大小和数据宽度外8通道LPD和FPD DMA控制器在体系结构上是相同的。 Zynq UltraScale MPSOC是一种用来存储到存储、存储到IO、IO到存储、IO到IO传输的通用DMA其模块框图如下图所示 图21.1.2 DMA模块框图 AXI Direct Memory AccessAXI DMAIP内核在AXI4内存映射和AXI4-Stream IP接口之间提供高带宽直接储存访问。其可选的scatter gather功能还可以从基于处理器的系统中的中央处理单元CPU卸载数据移动任务。初始化、状态和管理寄存器通过AXI4-Lite从接口访问。核心的功能组成如下图所示 图21.1.3 AXI DMA框图 AXI DMA用到了三种总线AXI4-Lite用于对寄存器进行配置AXI4 Memory Map用于与内存交互又分为AXI4 Memory Map Read和AXI4 Memory Map Write两个接口一个是读一个是写。AXI4 Stream 接口用于对外设的读写其中AXI4 Stream MasterMM2SMemory Map to Stream用于对外设写AXI4-Stream Slave(S2MMStream to Memory Map)用于对外设读。总之在以后的使用中需要知道AXI_MM2S和AXI_S2MM是存储器端映射的AXI4总线提供对存储器DDR的访问。AXIS_MM2S和AXIS_S2MM是AXI4-streaming总线可以发送和接收连续的数据流无需地址。 AXI DMA提供3种模式分别是Direct Register模式、Scatter/Gather模式和Cyclic DMA模式这里我们简单的介绍下常用的Direct Register模式和Scatter/Gather模式。 Direct Register DMA模式也就是Simple DMA。Direct Register模式提供了一种配置用于在MM2S和S2MM通道上执行简单的DMA传输这需要更少的FPGA资源。Simple DMA允许应用程序在DMA和Device之间定义单个事务。它有两个通道一个从DMA到Device另一个从Device到DMA。应用程序必须设置缓冲区地址和长度字段以启动相应通道中的传输。 Scatter/Gather DMA模式允许在单个DMA事务中将数据传输到多个存储区域或从多个存储区域传输数据。它相当于将多个Simple DMA请求链接在一起。SGDMA允许应用程序在内存中定义事务列表硬件将在应用程序没有进一步干预的情况下处理这些事务。在此期间应用程序可以继续添加更多工作以保持硬件工作。用户可以通过轮询或中断来检查事务是否完成。SGDMA处理整个数据包被定义为表示消息的一系列数据字节并允许将数据包分解为一个或多个事务。例如采用以太网IP数据包该数据包由14字节的报头后跟1个或多个字节的有效负载组成。使用SGDMA应用程序可以将BDBuffer Descriptor用于描述事务的对象指向报头将另一个BD指向有效负载然后将它们作为单个消息传输。这种策略可以使TCP / IP堆栈更有效它允许将数据包标头和数据保存在不同的内存区域而不是将数据包组装成连续的内存块。 在本设计中不需要使用scatter gather DMA模式因为可以使用DMA的更简单的寄存器直接模式充分实现系统从而避免实现scatter gather功能带来的面积成本。在系统需要对DMA进行相对复杂的软件控制时可以使用scatter gather模式。 21.2实验任务 本章的实验任务是在MPSOC开发板上使用PL的AXI DMA IP核从DDR中读取数据并将数据写回到DDR中。 21.3硬件设计 在实际应用中DMA一般与产生数据或需求数据的IP核相连接该IP核可以是带有Stream接口的高速的AD模拟转数字或DA数字转模拟 IP核。不失一般性在本次实验中我们使用AXI4 Stream Data FIFO IP核来充当这类IP进行DMA环回实验。大致的系统框图如下 图 21.3.1 AXI DAM环路测试系统框图 PS开启Slave AXI HP和Master AXI HPM接口。AXI DMA和AXI4 Stream Data FIFO在PL中实现。处理器通过Master AXI HPM接口与AXI DMA通信以设置、启动和监控数据传输。数据传输通过Slave AXI HP接口。AXI DMA通过Slave AXI HP接口从DDR中读取数据后发送给AXI4 Stream Data FIFO这种情况下AXI4 Stream Data FIFO可以相当于带有Stream接口的高速DA。AXI DMA读取AXI4 Stream Data FIFO中的数据后通过Slave AXI HP接口写入DDR的情形AXI4 Stream Data FIFO相当于带有Stream接口的高速AD。 step1创建Vivado工程 打开Vivado创建一个名为“axi_dma_loop”的空白工程工程路径为F:\ZYNQ\Embedded_System\axi_dma_loop文件夹。注意工程名和路径只能由英文字母、数字和下划线组成不能包含中文、空格以及特殊字符 step2使用IP Integrator创建Processing System 2-1 在左侧导航栏Flow Navigator中单击IP Integrator下的Create Block Design。然后在弹出的对话框中指定所创建的Block Design的名称这里使用Design name栏中默认的“design_1”然后点击“OK”如下图所示 图 21.3.2 创建 Block Design 2-2 添加Zynq UltraScale MPSOC模块。接下来按照《“Hello World”实验》中的步骤2-7、2-8分别配置PS的UART和DDR控制器。需要特别注意的是我们在《“Hello World”实验》的步骤2-10中移除了PS中与PL端交互的接口信号这些接口在我们本次实验中需要予以保留。 2-3 配置时钟。 点击左侧的Clock Configuration页面然后在右侧界面中打开Output Clocks标签页依次展开Low Power Domain Clocks-PL Fabric Clocks可以看到默认勾选PL0且时钟频率为100MHz这里我们使用默认的100MHz如下图所示 图 21.3.3 配置pl_clk0 2-4 开启HP接口。 点击左侧的PS-PL Configuration页面然后依次展开PS-PL Interfaces-Slave Interface-AXI HP勾选AXI HP0 FPD数据位宽使用默认的128bit位宽如下图所示 图 21.3.4 启用HP0接口 2-5 因为DMA在传输完成后通过发送中断通知CPU所以我们需要开启PL到PS的中断。 还是在PS-PL Configuration界面中依次展开General-Interrupts-PL to PS设置IRQ0[0:7]为1如下图所示 图 21.3.5 开启PL到PS的中断 2-6 配置Zynq UltraScale MPSOC模块完成点击“OK”配置完成后的Zynq UltraScale MPSOC模块如下图所示 图 21.3.6 配置完成后的Zynq UltraScale MPSOC IP 2-7 添加DMA IP。 添加DMA IP如同添加Zynq UltraScale MPSOC IP只不过搜索词由MPSOC变为dma如下图所示 图 21.3.7 添加DMA模块 图 21.3.8 配置DMA模块 我们双击axi_dma_0打开配置界面如图 21.3.8所示此处我们只需要取消勾选Enable Scatter Gather Engine即可。不过还是介绍下与配置相关的选项。 Enable Scatter Gather Engine 选中此选项可启用Scatter Gather模式操作并在AXI DMA中包含Scatter Gather Engine。取消选中此选项可启用Direct Register模式操作但不包括AXI DMA中的Scatter Gather Engine。禁用Scatter Gather Engine会使Scatter/Gather Engine的所有输出端口都绑定为零并且所有输入端口都将保持打开状态。此处我们取消勾选Enable Scatter Gather Engine。 Enable Micro DMA 选中此选项会生成高度优化的DMA资源数量较少。此设置可用于传输极少量数据的应用程序。此处我们不勾选。 Width of Buffer Length Register 此整数值指定用于控制字段缓冲区长度的有效位数和在Scatter/Gather描述符中传输的Status字段的字节数。字节数等于。因此长度为26时字节数为字节。对于多通道模式此值应设置为23。此处我们保持默认设置14。 Address Width (32 - 64) 指定地址空间的宽度可以是32到64之间的任何值。此处保持默认值32。 Enable Read Channel 开启AXI DMA的读通道MM2S相关选项如下 Number of Channels指定通道数。保持默认值1。 Memory Map Data WidthAXI MM2S存储映射读取数据总线的数据位宽。有效值为32、64、128、256、512和1024。此处保持默认值32。 Stream Data WidthAXI MM2S AXI4-Stream数据总线的数据位宽。该值必须小于或等于Memory Map Data Width。有效值为8、16、32、64、128、512和1024。此处保持默认值32。 Max Burst Size突发分区粒度设置。此设置指定MM2S的AXI4-Memory Map侧的突发周期的最大大小。有效值为2、4、8、16、32、64、128和256。此处保持默认值16。 Allow Unaligned Transfers启用或禁用MM2S数据重新排列引擎Data Realignment EngineDRE。选中时DRE被使能并允许在MM2S存储映射数据路径上数据重新对齐到8位的字节水平。对于MM2S通道从内存中读取数据。如果DRE被使能则数据读取可以从任何缓冲区地址字节偏移开始并且读取数据被对齐使得第一个字节读取是AXI4-Stream上的第一个有效字节输出。 注意如果为相应通道禁用DRE则不支持未对齐的缓冲区、源或目标地址。在禁用DRE的情况下使用未对齐的地址会产生未定义的结果。DRE支持仅适用于512位及以下的AXI4-Stream数据宽度设置。 Enable Write Channel 开启AXI DMA的写通道S2MM相关选项可参考读通道。 2-8 添加axis_data_fifo IP 图 21.3.9 添加axis_data_fifo IP 该IP保持默认设置即可。添加该IP核的重点不是了解该IP核如何使用而是知道该IP核带有AXI4 Stream接口。在以后的实际使用中需要封装自定义IP核时要注意这一点。 2-9 添加Concat IP。 Concate IP 实现了单个分散的信号整合成总线信号。这里2个独立的中断信号可以合并在一起接入到Zynq UltraScale MPSOC IP的中断信号上。 图 21.3.10 添加Concat IP 2-10 模块连接。 在Diagram窗口中点击“Run connection Automation”进行自动连接在弹出的界面中勾选“All Automation”然后点击OK如下图所示 图 21.3.11 Run connection Automation 2-11 自动连接完成后发现Concat IP未连接我们手动进行连接如下图所示 图21.3.12 手动连接Concat IP 另外添加的axis_data_fifo也未连接我们同样手动连接。首先将DMA的M_AXIS_MM2S端口与axis_data_fifo的S_AXIS进行连接如下图所示 图21.3.13 连接axis_data_fifo的S_AXIS 然后将axis_data_fifo上的M_AXIS端口连接到DMA的S_AXIS_S2MM端口如下图所示 图21.3.14 连接axis_data_fifo上的M_AXIS 现在我们连接axis_data_fifo的时钟和复位。单击axis_data_fifo的s_axis_aresetn端口并将其连接到DMA的axi_resetn端口单击axis_data_fifo的s_axis_aclk端口并将其连接到DMA的m_axi_mm2s_aclk端口如下图所示 图21.3.15 axis_data_fifo的时钟和复位 2-12 再次点击Run Connection Automation然后右击空白处选择Regenerate Layout重新布局最终的IP模块连接图如下图所示 图21.3.16 模块连接图 2-13 到这里我们的Block Design就设计完成了按“F6”键进行“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误点击“OK”确认。最后按快捷键“Ctrl S”保存设计。 step3生成顶层HDL模块 3-1 在Sources窗口中选中Design Sources下的design_1.bd, 这就是我们刚刚完成的Block Design设计。右键点击design_1.bd然后依次执行“Generate Output Products”和“Create HDL Wrapper”。注意在执行“Generate Output Products”步骤时受电脑配置的影响软件运行时间会较长要等待一会。 step4生成Bitstream文件并导出Hardware 4-1 在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG点击该选项中的“Generate Bitstream”。在连续弹出的对话框中依次点击“YES”、“OK”。然后 Vivado 工具开始依次对设计进行综合、实现、并生成 Bitstream 文件。 4-2 导出硬件。 在生成Bitstream之后在菜单栏中选择 File Export Export hardware导出硬件并在弹出的对话框中勾选“Include bitstream”。将导出的“design_1_wrapper.xsa”文件放到vitis文件夹然后在菜单栏选择Tools Launch Vitis启动VITIS软件。 21.4软件设计 step5在VITIS中创建应用工程 5-1 在VITIS软件中新建一个名为“axi_dma_loop”的空白应用工程。 5-2 为应用工程新建一个名为“main.c”源文件我们在新建的main.c文件中输入本次实验的代码。代码的主体部分如下所示 1 /***************************** Include Files *********************************/ 2 3 #include xaxidma.h 4 #include xparameters.h 5 #include xil_exception.h 6 #include xscugic.h 7 8 /************************** Constant Definitions *****************************/ 9 10 #define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID 11 #define RX_INTR_ID XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID 12 #define TX_INTR_ID XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID 13 #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID 14 #define DDR_BASE_ADDR XPAR_PSU_DDR_0_S_AXI_BASEADDR //0x00000000 15 #define MEM_BASE_ADDR (DDR_BASE_ADDR 0x1100000) //0x01100000 16 #define TX_BUFFER_BASE (MEM_BASE_ADDR 0x00100000) //0x01200000 17 #define RX_BUFFER_BASE (MEM_BASE_ADDR 0x00300000) //0x01400000 18 #define RESET_TIMEOUT_COUNTER 10000 //复位时间 19 #define TEST_START_VALUE 0x0 //测试起始值 20 #define MAX_PKT_LEN 0x100 //发送包长度 21 22 /************************** Function Prototypes ******************************/ 23 24 static int check_data(int length, u8 start_value); 25 static void tx_intr_handler(void *callback); 26 static void rx_intr_handler(void *callback); 27 static int setup_intr_system(XScuGic * int_ins_ptr, XAxiDma * axidma_ptr, 28 u16 tx_intr_id, u16 rx_intr_id); 29 static void disable_intr_system(XScuGic * int_ins_ptr, u16 tx_intr_id, 30 u16 rx_intr_id); 31 32 /************************** Variable Definitions *****************************/ 33 34 static XAxiDma axidma; //XAxiDma实例 35 static XScuGic intc; //中断控制器的实例 36 volatile int tx_done; //发送完成标志 37 volatile int rx_done; //接收完成标志 38 volatile int error; //传输出错标志 39 40 /************************** Function Definitions *****************************/ 41 42 int main(void) 43 { 44 int i; 45 int status; 46 u8 value; 47 u8 *tx_buffer_ptr; 48 u8 *rx_buffer_ptr; 49 XAxiDma_Config *config; 50 51 tx_buffer_ptr (u8 *) TX_BUFFER_BASE; 52 rx_buffer_ptr (u8 *) RX_BUFFER_BASE; 53 54 xil_printf(\r\n--- Entering main() --- \r\n); 55 56 config XAxiDma_LookupConfig(DMA_DEV_ID); 57 if (!config) { 58 xil_printf(No config found for %d\r\n, DMA_DEV_ID); 59 return XST_FAILURE; 60 } 61 62 //初始化DMA引擎 63 status XAxiDma_CfgInitialize(axidma, config); 64 if (status ! XST_SUCCESS) { 65 xil_printf(Initialization failed %d\r\n, status); 66 return XST_FAILURE; 67 } 68 69 if (XAxiDma_HasSg(axidma)) { 70 xil_printf(Device configured as SG mode \r\n); 71 return XST_FAILURE; 72 } 73 74 //建立中断系统 75 status setup_intr_system(intc, axidma, TX_INTR_ID, RX_INTR_ID); 76 if (status ! XST_SUCCESS) { 77 xil_printf(Failed intr setup\r\n); 78 return XST_FAILURE; 79 } 80 81 //初始化标志信号 82 tx_done 0; 83 rx_done 0; 84 error 0; 85 86 value TEST_START_VALUE; 87 for (i 0; i MAX_PKT_LEN; i) { 88 tx_buffer_ptr[i] value; 89 value (value 1) 0xFF; 90 } 91 92 Xil_DCacheFlushRange((UINTPTR) tx_buffer_ptr, MAX_PKT_LEN); //刷新Data Cache 93 94 status XAxiDma_SimpleTransfer(axidma, (UINTPTR) tx_buffer_ptr, 95 MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE); 96 if (status ! XST_SUCCESS) { 97 return XST_FAILURE; 98 } 99 100 status XAxiDma_SimpleTransfer(axidma, (UINTPTR) rx_buffer_ptr, 101 MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA); 102 if (status ! XST_SUCCESS) { 103 return XST_FAILURE; 104 } 105 106 Xil_DCacheFlushRange((UINTPTR) rx_buffer_ptr, MAX_PKT_LEN); //刷新Data Cache 107 while (!tx_done !rx_done !error) 108 ; 109 //传输出错 110 if (error) { 111 xil_printf(Failed test transmit%s done, 112 receive%s done\r\n, tx_done ? : not, 113 rx_done ? : not); 114 goto Done; 115 } 116 117 //传输完成检查数据是否正确 118 status check_data(MAX_PKT_LEN, TEST_START_VALUE); 119 if (status ! XST_SUCCESS) { 120 xil_printf(Data check failed\r\n); 121 goto Done; 122 } 123 124 xil_printf(Successfully ran AXI DMA Loop\r\n); 125 disable_intr_system(intc, TX_INTR_ID, RX_INTR_ID); 126 127 Done: xil_printf(--- Exiting main() --- \r\n); 128 return XST_SUCCESS; 129 }在代码的第14行我们重新宏定义了XPAR_PSU_DDR_0_S_AXI_BASEADDR即DDR的基址打开XPAR_PSU_DDR_0_S_AXI_BASEADDR的定义处我们可以看到DDR的基址为0x00000000如下图所示 图 21.4.1 DDR的地址映射 从而DMA读取数据的起始地址TX_BUFFER_BASE为0x01200000写入到DDR中的起始地址RX_BUFFER_BASE为0x01400000。代码第19行TEST_START_VALUE为测试起始值此处我们将其设为0x0也可以改为其它任意值。第20行的MAX_PKT_LEN是DMA传输的数据包的长度此处为0x100即256。 代码第42行的main函数是程序的主体。第63行的XAxiDma_CfgInitialize函数初始化DMA引擎第75行的setup_intr_system函数建立DMA中断系统。第87~90行向DDR的指定地址写入数据写入的第一个地址为TX_BUFFER_BASE即0x01200000值为TEST_START_VALUE即0x0写入的地址长度为MAX_PKT_LEN即0x100。DMA从TX_BUFFER_BASE读取数据长度为MAX_PKT_LE的数据然后写入到地址RX_BUFFER_BAS处。第92行的Xil_DcacheFlushRange函数刷新Data Cache以防Data Cache缓存数据。从第95行到第105行配置并开启DMA传输数据。第107行再次刷新Data Cache由于DDR中的数据已经更新但Cache中的数据并没有更新CPU如果想从DDR中读取数据需要刷新Data Cache。此处使用Xil_DcacheFlushRange函数也可以使用Xil_DcacheInvalidateRange函数使Data Cache指定范围的数据无效函数调用方法相同。第118行的check_data函数检查当DMA传输完成后写入的数据是否正确。第125行的disable_intr_system函数取消DMA中断。 主函数main中调用的自定义函数实现如下 131 //检查数据缓冲区 132 static int check_data(int length, u8 start_value) 133 { 134 u8 value; 135 u8 *rx_packet; 136 int i 0; 137 138 value start_value; 139 rx_packet (u8 *) RX_BUFFER_BASE; 140 for (i 0; i length; i) { 141 if (rx_packet[i] ! value) { 142 xil_printf(Data error %d: %x/%x\r\n, i, rx_packet[i], value); 143 return XST_FAILURE; 144 } 145 value (value 1) 0xFF; 146 } 147 148 return XST_SUCCESS; 149 } 150 151 //DMA TX中断处理函数 152 static void tx_intr_handler(void *callback) 153 { 154 int timeout; 155 u32 irq_status; 156 XAxiDma *axidma_inst (XAxiDma *) callback; 157 158 //读取待处理的中断 159 irq_status XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DMA_TO_DEVICE); 160 //确认待处理的中断 161 XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DMA_TO_DEVICE); 162 163 //Tx出错 164 if ((irq_status XAXIDMA_IRQ_ERROR_MASK)) { 165 error 1; 166 XAxiDma_Reset(axidma_inst); 167 timeout RESET_TIMEOUT_COUNTER; 168 while (timeout) { 169 if (XAxiDma_ResetIsDone(axidma_inst)) 170 break; 171 timeout - 1; 172 } 173 return; 174 } 175 176 //Tx完成 177 if ((irq_status XAXIDMA_IRQ_IOC_MASK)) 178 tx_done 1; 179 } 180 181 //DMA RX中断处理函数 182 static void rx_intr_handler(void *callback) 183 { 184 u32 irq_status; 185 int timeout; 186 XAxiDma *axidma_inst (XAxiDma *) callback; 187 188 irq_status XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DEVICE_TO_DMA); 189 XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DEVICE_TO_DMA); 190 191 //Rx出错 192 if ((irq_status XAXIDMA_IRQ_ERROR_MASK)) { 193 error 1; 194 XAxiDma_Reset(axidma_inst); 195 timeout RESET_TIMEOUT_COUNTER; 196 while (timeout) { 197 if (XAxiDma_ResetIsDone(axidma_inst)) 198 break; 199 timeout - 1; 200 } 201 return; 202 } 203 204 //Rx完成 205 if ((irq_status XAXIDMA_IRQ_IOC_MASK)) 206 rx_done 1; 207 } 208 209 //建立DMA中断系统 210 // param int_ins_ptr是指向XScuGic实例的指针 211 // param AxiDmaPtr是指向DMA引擎实例的指针 212 // param tx_intr_id是TX通道中断ID 213 // param rx_intr_id是RX通道中断ID 214 // return成功返回XST_SUCCESS否则返回XST_FAILURE 215 static int setup_intr_system(XScuGic * int_ins_ptr, XAxiDma * axidma_ptr, 216 u16 tx_intr_id, u16 rx_intr_id) 217 { 218 int status; 219 XScuGic_Config *intc_config; 220 221 //初始化中断控制器驱动 222 intc_config XScuGic_LookupConfig(INTC_DEVICE_ID); 223 if (NULL intc_config) { 224 return XST_FAILURE; 225 } 226 status XScuGic_CfgInitialize(int_ins_ptr, intc_config, 227 intc_config-CpuBaseAddress); 228 if (status ! XST_SUCCESS) { 229 return XST_FAILURE; 230 } 231 232 //设置优先级和触发类型 233 XScuGic_SetPriorityTriggerType(int_ins_ptr, tx_intr_id, 0xA0, 0x3); 234 XScuGic_SetPriorityTriggerType(int_ins_ptr, rx_intr_id, 0xA0, 0x3); 235 236 //为中断设置中断处理函数 237 status XScuGic_Connect(int_ins_ptr, tx_intr_id, 238 (Xil_InterruptHandler) tx_intr_handler, axidma_ptr); 239 if (status ! XST_SUCCESS) { 240 return status; 241 } 242 243 status XScuGic_Connect(int_ins_ptr, rx_intr_id, 244 (Xil_InterruptHandler) rx_intr_handler, axidma_ptr); 245 if (status ! XST_SUCCESS) { 246 return status; 247 } 248 249 XScuGic_Enable(int_ins_ptr, tx_intr_id); 250 XScuGic_Enable(int_ins_ptr, rx_intr_id); 251 252 //启用来自硬件的中断 253 Xil_ExceptionInit(); 254 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, 255 (Xil_ExceptionHandler) XScuGic_InterruptHandler, 256 (void *) int_ins_ptr); 257 Xil_ExceptionEnable(); 258 259 //使能DMA中断 260 XAxiDma_IntrEnable(axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE); 261 XAxiDma_IntrEnable(axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA); 262 263 return XST_SUCCESS; 264 } 265 266 //此函数禁用DMA引擎的中断 267 static void disable_intr_system(XScuGic * int_ins_ptr, u16 tx_intr_id, 268 u16 rx_intr_id) 269 { 270 XScuGic_Disconnect(int_ins_ptr, tx_intr_id); 271 XScuGic_Disconnect(int_ins_ptr, rx_intr_id); 272 }代码第132行起的check_data函数用于检查写入到DDR中的数据是否正确。 代码第152行起的DMA TX中断处理函数tx_intr_handler用于处理DMA发送中断。首先通过XAxiDma_IntrGetIrq函数读取待处理的中断然后使用XAxiDma_IntrAckIrq函数确认待处理的中断。如果发现是接收出现错误的中断则使用XAxiDma_Reset函数复位DMA并使用XAxiDma_ResetIsDone函数判断是否复位完成。如果是发送完成的中断则置位发送完成标志tx_done。代码第182行起的DMA RX中断处理函数与此类似。 代码第215行起的建立DMA中断系统函数setup_intr_system首先初始化中断控制器驱动然后使用XScuGic_SetPriorityTriggerType函数设置DMA的优先级和触发类型。XScuGic_Connect函数为中断设置中断处理函数因为有发送中断和接收中断所以需要分别设置。XScuGic_Enable函数用于使能DMA发送中断和DMA接收中断源。最后启用来自硬件的中断和使用XAxiDma_IntrEnable函数使能DMA中断。 5-3 我们按快捷键CtrlS保存 main.c 文件右击应用工程名选择Build Project编译工程。编译完成后 Console 中会出现提示信息“Build Finished”同时生成elf文件。 21.5下载验证 首先我们将下载器与开发板上的JTAG接口连接下载器另外一端与电脑连接。然后使用USB连接线将USB_UART(开发板PS PORT)接口与电脑连接用于串口通信。最后连接开发板的电源给开发板上电。 step6板级验证 6-1 进入Debug模式。在前面的实验中我们右击应用工程名Run As选择第一项“Launch on Hardware”下载程序。本实验我们换一种方法。右击应用工程名Debug As选择第一项“Launch on Hardware”进入调试界面如下图所示 图21.5.1 进入Debug模式 然后在串口终端(Vitis Serial Terminal)中点击箭头处的加号设置端口号端口号可以通过自己电脑设备管理器查看这里选择COM9。 6-2 设置Memory Monitors。 在调试界面Memory窗口中添加需要监视的储存器地址。首先我们添加地址0x1200000也就是DMA从DDR中读取数据的起始地址TX_BUFFER_BASE添加方式如下图所示 图21.5.2 添加监视存储地址0x1200000 在新添加的Memory监视界面的空白处右击在弹出的菜单栏中选择“Format…”设置“Column Size”为1分别如图21.5.3和图21.5.4所示 图21.5.3 设置数据显示格式 图21.5.4 设置Column Size大小 设置完成后如下图所示这样可以更方便观察数据。可以看到刚下载完程序后DDR中地址0x1200000处的值为0x71。 图21.5.5 0x1200000地址处的值 现在我们按照同样的方式添加并设置地址0x1400000也就是DMA将数据写回DDR中的起始地址RX_BUFFER_BASE。从下图可以看到刚下载完程序后DDR的0x1400000地址处的值为0x71。 图21.5.6 0x1400000地址处的值 6-3 设置运行断点。 我们在程序的以下几个地方设置断点。 图21.5.7 设置断点 6-4 按F8先将程序运行到断点1处(113行)此时从Memory Monitors中可以看到0x1200000地址处的值变为00紧随其后的地址的数据值逐次递增1。由于CPU与DDR之间是通过Cache 交互的数据暂存在Cache中没有刷新Data Cache数据到DDR显示的数据是Data Cache中的。 图21.5.8 0x1200000地址数据变化 接着运行到断点2处(115行) Data Cache中的数据已经刷新到DDR4中。此时我们将Memory Monitors窗口中的监视内容切换到0x1400000看看地址0x1400000处的数据是什么时候更新的点击左侧的0x1400000即可切换。运行到断点3处(121行)执行完第115行的DMA发送函数完成从内存中读取数据传输给外设即DMA从地址0x1200000处读取数据传输给外设此时地址0x1400000处的数据未更新。运行到断点4处(127行)执行完第121行的DMA接收函数完成从外设读取数据写入到内存即将刚才写入到外设的数据读取出来并从DDR的地址0x1400000处开始写入不过此时我们从下图发现地址0x1400000处的数据还是未更新。其实此时DDR中的数据已经更新只不过我们Data Cache中的数据未更新而Memory Monitors窗口显示的正是Data Cache中的数据所以需要刷新Data Cache。 图21.5.9 0x1400000地址数据未变化 接着运行到断点5处(128行)刷新Data Cache后此时我们发现地址0x1400000处的值变为00紧随其后的地址处的数据都变成预期的值。 图21.5.10 刷新Data Cache后0x1400000地址数据变化 到此使用DMA从DDR中读取数据并将数据写回到DDR中的实验任务就完成了。按F6继续往下执行到程序结束在下方的 VITIS Terminal 中可以看到应用程序打印的信息如下图所示 图21.5.11 串口终端中打印的信息
http://www.dnsts.com.cn/news/69461.html

相关文章:

  • 外贸做中英文网站企业网站欣赏
  • 建站宝盒东莞人才市场招聘信息2023
  • 西安苗木行业网站建设价格保定seo管理
  • 如何增加网站外链wordpress离线更新
  • 怎样暂停域名指向网站wordpress博客加相册
  • 成品ppt的网站免费观看足球网站模板下载
  • 佛山做网站公司哪家好wordpress 仪表盘美化
  • 网站的跳出率很高做的好微信商城网站吗
  • 谷歌seo专员seo工具
  • 国外比较好的建筑设计网站广东建设工程注册中心网站
  • 怎么做淘宝客手机网站推广北大青鸟网站建设课程
  • 自己做信息网站网页模板下载在线
  • 文化事业建设费在哪个网站申报融资平台哪家好
  • 网站推广在线推广网页设计思路说明200字
  • 制作卖东西网站新东方考研培训机构官网
  • 东莞公司网站怎么做自己做微信团购小程序
  • 青海专业网页设计免费建站做瞹瞹爱免费网站
  • 嘉兴做微网站的公司上海正规做网站公司电话
  • 北京建网站公司飞沐新媒体管家wordpress
  • 新网站如何做快照门户网站建设 增强责任意识
  • 怎样才能建设网站家具网站模板下载
  • 海北公司网站建设多少钱帝国cms如何做网站
  • 郑州高端品牌网站建设网页设计尺寸是多少
  • 网站怎么做好凡科快图一键抠图
  • 宏升温岭网站建设百度点击排名收费软件
  • 做网站用c 还是js做兼职的设计网站
  • 网站上线模板管理系统平台
  • 厦门 外贸公司做网站正邦设计有限公司
  • 做网站准备内容小程序代理公司
  • 仿漫画网站建设定制小说网站系统源码建设深圳信息网