zynq板zedboard+vitis设计(二)AXI DMA

news/2025/1/13 7:56:24/

前言

本期将AXI DMA的写入与读取的测试,一些工程建立的详细步骤在第一次文章已经详细介绍了,此处不再赘述。

1.vivado中建立Block Design并导出hardware

新建vivado工程并创建block design,添加zynq模块,选用zedboard预设

 双击zynq模块进行编辑,这里勾选S AXI HP0接口

打开中断接口,然后点击确认完成zynq设置

搜索添加DMA模块

 取消S/G模式,其他保持默认

搜索添加FIFO,保持默认设置

添加concat模块,用于将多个接口合并

 

 连续点击两次run connection automation后点击run block automation

 如图连接DMA、concat以及zynq三个模块

如图连接DMA和data FIFO,注意端口名称

 将data FIFO中的时钟与复位端口手动连接

 完成block design设计

依次进行generate output products、create HDL wrapper、generate bitstream以及 export hardware操作,注意导出hardware时要勾选include bitstream。

2.vitis部分

打开vitis新建工程,并添加mian.c文件

#include "xaxidma.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xscugic.h"#define DMA_DEV_ID          XPAR_AXIDMA_0_DEVICE_ID
#define RX_INTR_ID          XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID
#define TX_INTR_ID          XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID
#define INTC_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID	//以上四步分别是重定义DMA以及中断的ID
#define DDR_BASE_ADDR       XPAR_PS7_DDR_0_S_AXI_BASEADDR   //DDR基地址
#define MEM_BASE_ADDR       (DDR_BASE_ADDR + 0x1000000)
#define TX_BUFFER_BASE      (MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE      (MEM_BASE_ADDR + 0x00300000)
#define RESET_TIMEOUT_COUNTER   10000    //复位时间
#define TEST_START_VALUE        0x0      //测试起始值
#define DATA_LEN             0x100       //数据长度static int check_data(int length, u8 start_value);
static void tx_intr_handler(void *callback);
static void rx_intr_handler(void *callback);
static int setup_intr_system(XScuGic * int_ins_ptr, XAxiDma * axidma_ptr,u16 tx_intr_id, u16 rx_intr_id);
static void disable_intr_system(XScuGic * int_ins_ptr, u16 tx_intr_id,u16 rx_intr_id);static XAxiDma axidma;     //XAxiDma实例
static XScuGic intc;       //中断控制器的实例
volatile int tx_done;      //发送完成标志
volatile int rx_done;      //接收完成标志
volatile int error;        //传输出错标志int main(void)
{int i;int status;u8 value;u8 *tx_buffer_ptr;u8 *rx_buffer_ptr;XAxiDma_Config *config;tx_buffer_ptr = (u8 *) TX_BUFFER_BASE;rx_buffer_ptr = (u8 *) RX_BUFFER_BASE;xil_printf("\r\n--- Entering main() --- \r\n");config = XAxiDma_LookupConfig(DMA_DEV_ID);if (!config) {xil_printf("No config found for %d\r\n", DMA_DEV_ID);return XST_FAILURE;}//初始化DMA引擎status = XAxiDma_CfgInitialize(&axidma, config);if (status != XST_SUCCESS) {xil_printf("Initialization failed %d\r\n", status);return XST_FAILURE;}if (XAxiDma_HasSg(&axidma)) 		//该函数用来检测DMA是普通模式还是S/G模式{xil_printf("Device configured as SG mode \r\n");return XST_FAILURE;}//建立中断系统status = setup_intr_system(&intc, &axidma, TX_INTR_ID, RX_INTR_ID);if (status != XST_SUCCESS) {xil_printf("Failed intr setup\r\n");return XST_FAILURE;}//初始化标志信号tx_done = 0;rx_done = 0;error   = 0;value = TEST_START_VALUE;for (i = 0; i < DATA_LEN; i++) {tx_buffer_ptr[i] = value;value = (value + 1) & 0xFF;}Xil_DCacheFlushRange((UINTPTR) tx_buffer_ptr, DATA_LEN);   //刷新Data Cachestatus = XAxiDma_SimpleTransfer(&axidma, (UINTPTR) tx_buffer_ptr,DATA_LEN, XAXIDMA_DMA_TO_DEVICE);if (status != XST_SUCCESS) {return XST_FAILURE;}status = XAxiDma_SimpleTransfer(&axidma, (UINTPTR) rx_buffer_ptr,DATA_LEN, XAXIDMA_DEVICE_TO_DMA);if (status != XST_SUCCESS) {return XST_FAILURE;}Xil_DCacheFlushRange((UINTPTR) rx_buffer_ptr, DATA_LEN);   //刷新Data Cachewhile (!tx_done && !rx_done && !error);//传输出错if (error) {xil_printf("Failed test transmit%s done, ""receive%s done\r\n", tx_done ? "" : " not",rx_done ? "" : " not");goto Done;}//传输完成,检查数据是否正确status = check_data(DATA_LEN, TEST_START_VALUE);if (status != XST_SUCCESS) {xil_printf("Data check failed\r\n");goto Done;}xil_printf("Successfully ran AXI DMA Loop\r\n");disable_intr_system(&intc, TX_INTR_ID, RX_INTR_ID);Done: xil_printf("--- Exiting main() --- \r\n");return XST_SUCCESS;
}//检查数据缓冲区
static int check_data(int length, u8 start_value)
{u8 value;u8 *rx_packet;int i = 0;value = start_value;rx_packet = (u8 *) RX_BUFFER_BASE;for (i = 0; i < length; i++) {if (rx_packet[i] != value) {xil_printf("Data error %d: %x/%x\r\n", i, rx_packet[i], value);return XST_FAILURE;}value = (value + 1) & 0xFF;}return XST_SUCCESS;
}//DMA TX中断处理函数
static void tx_intr_handler(void *callback)
{int timeout;u32 irq_status;XAxiDma *axidma_inst = (XAxiDma *) callback;//读取待处理的中断irq_status = XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DMA_TO_DEVICE);//确认待处理的中断XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DMA_TO_DEVICE);//Tx出错if ((irq_status & XAXIDMA_IRQ_ERROR_MASK)) {error = 1;XAxiDma_Reset(axidma_inst);timeout = RESET_TIMEOUT_COUNTER;while (timeout) {if (XAxiDma_ResetIsDone(axidma_inst))break;timeout -= 1;}return;}//Tx完成if ((irq_status & XAXIDMA_IRQ_IOC_MASK))tx_done = 1;
}//DMA RX中断处理函数
static void rx_intr_handler(void *callback)
{u32 irq_status;int timeout;XAxiDma *axidma_inst = (XAxiDma *) callback;irq_status = XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DEVICE_TO_DMA);XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DEVICE_TO_DMA);//Rx出错if ((irq_status & XAXIDMA_IRQ_ERROR_MASK)) {error = 1;XAxiDma_Reset(axidma_inst);timeout = RESET_TIMEOUT_COUNTER;while (timeout) {if (XAxiDma_ResetIsDone(axidma_inst))break;timeout -= 1;}return;}//Rx完成if ((irq_status & XAXIDMA_IRQ_IOC_MASK))rx_done = 1;
}//建立DMA中断系统
//  @param   int_ins_ptr是指向XScuGic实例的指针
//  @param   AxiDmaPtr是指向DMA引擎实例的指针
//  @param   tx_intr_id是TX通道中断ID
//  @param   rx_intr_id是RX通道中断ID
//  @return:成功返回XST_SUCCESS,否则返回XST_FAILURE
static int setup_intr_system(XScuGic * int_ins_ptr, XAxiDma * axidma_ptr,u16 tx_intr_id, u16 rx_intr_id)
{int status;XScuGic_Config *intc_config;//初始化中断控制器驱动intc_config = XScuGic_LookupConfig(INTC_DEVICE_ID);if (NULL == intc_config) {return XST_FAILURE;}status = XScuGic_CfgInitialize(int_ins_ptr, intc_config,intc_config->CpuBaseAddress);if (status != XST_SUCCESS) {return XST_FAILURE;}//设置优先级和触发类型XScuGic_SetPriorityTriggerType(int_ins_ptr, tx_intr_id, 0xA0, 0x3);XScuGic_SetPriorityTriggerType(int_ins_ptr, rx_intr_id, 0xA0, 0x3);//为中断设置中断处理函数status = XScuGic_Connect(int_ins_ptr, tx_intr_id,(Xil_InterruptHandler) tx_intr_handler, axidma_ptr);if (status != XST_SUCCESS) {return status;}status = XScuGic_Connect(int_ins_ptr, rx_intr_id,(Xil_InterruptHandler) rx_intr_handler, axidma_ptr);if (status != XST_SUCCESS) {return status;}XScuGic_Enable(int_ins_ptr, tx_intr_id);XScuGic_Enable(int_ins_ptr, rx_intr_id);//启用来自硬件的中断Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler) XScuGic_InterruptHandler,(void *) int_ins_ptr);Xil_ExceptionEnable();//使能DMA中断XAxiDma_IntrEnable(&axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);XAxiDma_IntrEnable(&axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);return XST_SUCCESS;
}//此函数禁用DMA引擎的中断
static void disable_intr_system(XScuGic * int_ins_ptr, u16 tx_intr_id,u16 rx_intr_id)
{XScuGic_Disconnect(int_ins_ptr, tx_intr_id);XScuGic_Disconnect(int_ins_ptr, rx_intr_id);
}

mian.c中文件内容如图(程序参照正点原子zynq教程中AXI DMA环回试验)

该程序先是用DMA将从0到100的100个数据存入DDR中,然后再用DMA读取出来,并进行验证,验证的方法是将读取出来的数与写入的进行逐个对比,以此完成一次环回试验。

 连接好开发板后下载运行,右下角terminal内输出完成提示。


http://www.ppmy.cn/news/180683.html

相关文章

Xilinx ZYNQ简介之Zynq® UltraScale+™系列

一、Zynq-7000 系列 ZYNQ (全称是 Zynq-7000 All Programmable SoC全可编程片上系统APSoC)是赛灵思公司(Xilinx)推出的新一代全可编程片上系统(APSoC),它将处理器的软件可编程性与 FPGA 的硬件可编程性进行完美整合,以提供无与伦比的系统性能、灵活性与可扩展性。与传…

Zepto

目录 一、Zepto初体验 1.1 什么是Zepto? 1.2 .既然和jQuery差不多, 为什么还需要Zepto? 1.3 官方网址 1.4 Zepto的特点 1.5 Zepto注意点 1.6 示例 二、Zepto选择器 2.1 示例 三、Zepto动画 3.1 zepto动画注意点 3.2 示例 四、Zepto-tap事件 4.1 移动端click事件…

Z字形转换

题目:Z字形转换 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数&#xff1a; P A H N A P L S I I G Y I R 之后从左往右&#xff0c;逐行读取字符&#xff1a;"PAHNAPLSIIGYIR" 实现一个将字符串进行指定行数变换的函数: string conv…

PYNQ-Z2快速上手教程

可进qq群进行相关Verilog知识交流&#xff1a;1073030956 1.准备工作 在开始之前&#xff0c;你需要准备好如下物品&#xff1a; PYNQ-Z2开发板装有最新版本Chrome浏览器的PC机一根百兆/千兆网线一根Micro USB线至少8GB大小的Micro SD卡和读卡器下载安装putty串口软件 2.制…

01、Zynq简介

00、Zynq简介 Zynq—7000 系列是赛灵思公司&#xff08;Xilinx&#xff09;推出的全可编程片上系统&#xff08;All Programmable SoC&#xff09;&#xff0c;全可编程是指软件可编程以及硬件可编程&#xff0c;包含 PS&#xff08;Processing System&#xff0c;处理器系统&…

PYNQ-Z2开机测试

前期准备 在淘宝买了块P2&#xff0c;950版本&#xff0c;只有一块板卡&#xff0c;其他什么也没有。所以需要准备以下&#xff1a;1、一张8GB以上的micro SD卡&#xff1b;2、一根网线&#xff1b;3、安卓手机充电线一根&#xff1b;4、SD读卡器一个。5、路由器&#xff08;这…

Z-Turn(ZYNQ)板卡移植petalinux操作系统

一、安装petalinux 1.安装虚拟机&#xff0c;在虚拟机里安装linux系统&#xff08;ubuntu 16.04&#xff09; 虚拟机里磁盘尽量预留多一点&#xff0c;建议60G以上&#xff0c;我的是80G建议安装VMware Tools虚拟机开发工具&#xff1a;vivado 2017.4(Windows) petalinux 20…

STM32F103ZET6

一、芯片型号说明及一些基本信息&#xff1a; 1. STM32 F 103 Z E T 6 STM32&#xff1a;代表 ARM Conte-x 内核的32位微控制器F&#xff1a;代表芯片子系列103&#xff1a;代表增强型系列Z&#xff1a;这一项代表引脚数&#xff0c;其中T代表36脚、C代表48脚、R代表64脚、V…