米尔科技ZYNQ -Linux下的DMA驱动

本文介绍了如何在米尔科技的ZYNQ开发板上实现Linux下的DMA驱动,并进行了中断测试。使用了Direct Register Mode,硬件配置包括开启DMA中断的PL-PS连接。代码实现涉及驱动、测试代码以及Makefile,最终测试结果显示程序运行成功。
摘要由CSDN通过智能技术生成

一.目标
在米尔科技的z-turn板上实现linux下的DMA驱动,同时对DMA中断进行测试。
二.分析
ZYNQ的AXIDMA有Direct Register Mode和Scatter/Gather Mode,本文使用的是Direct Register Mode。
Vivado上PL端的构造如下图所示,开启了DMA中断(PL-PS中断)。对于AXI-DMA来说,CPU通过S_AXI_LITE得出DMA地址,通过GP接口与S_AXI_相连,用于写数据,通过HP接口读入数据。
AXI_DMA_0的物理地址为:0x4040_0000。
在这里插入图片描述
对于DMA的操作可以查看手册相关寄存器如下图所示。
在这里插入图片描述
这里就不一一说明每个寄存器的功能了,详情请查看手册或查看:
https://www.cnblogs.com/yiwenbo/p/10500060.html

三.代码实现
①驱动代码

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <linux/dma-mapping.h>
/**
 *DMA驱动程序
 *
 *
 *
 *
 *
 *
 *`
 *
 * **/
//DMA 基地址
#define DMA_BASE_ADDR		0X40400000

//DMA MM2S控制寄存器
volatile unsigned int  * mm2s_cr;
#define MM2S_DMACR		0X00000000

//DMA MM2S状态控制寄存器
volatile unsigned int * mm2s_sr;
#define MM2S_DMASR		0X00000004

//DMA MM2S源地址低32位
volatile unsigned int * mm2s_sa;
#define MM2S_SA			0X00000018

//DMA MM2S传输长度(字节)
volatile unsigned int * mm2s_len;
#define MM2S_LENGTH		0X00000028

//DMA S2MM控制寄存器
volatile unsigned int  * s2mm_cr;
#define S2MM_DMACR		0X00000030

//DMA S2MM状态控制寄存器
volatile unsigned int  * s2mm_sr;
#define S2MM_DMASR		0X00000034

//DMA S2MM目标地址低32位
volatile unsigned int  * s2mm_da;
#define S2MM_DA			0X00000048

//DMA S2MM传输长度(字节)
volatile unsigned int  * s2mm_len;
#define S2MM_LENGTH		0X00000058

#define DMA_LENGTH		16384

dma_addr_t axidma_handle;
volatile unsigned int * axidma_addr;

//DMA interrupt functions
static irqreturn_t dma_mm2s_irq(int irq,void *dev_id)
{
   
    printk("irq=%d\n",irq);
    iowrite32(0x00001000,mm2s_sr);
    return IRQ_HANDLED;
}
static irqreturn_t dma_s2mm_irq(int irq,void *dev_id)
{
   
    printk("irq=%d\n",irq);
    iowrite32(0x00001000,s2mm_sr);
    return IRQ_HANDLED;
}
int major;

static struct class *dma_class   = NULL;
static int dma_init(void);
static int dma_exit(void);
static int dma_open(struct inode *inode,struct file *file);
static int 
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值