linux3.4.2之DMA驱动完整程序
/*
*参考arch/arm/mach-s3c24xx/dma-s3c2410.c
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/poll.h>
#include <plat/regs-dma.h>
#include <mach/dma.h>
#include <plat/dma-s3c24xx.h>
#include <linux/cdev.h>
#include <linux/backing-dev.h>
#include <linux/wait.h>
#include <linux/interrupt.h> #define DMA_BASE 0x4b000000
#define BUFF_SIZE 512 static unsigned char *src_addr;//源
static unsigned char *dst_addr;//目的
static int major;
static dma_addr_t psrc_addr;
static dma_addr_t pdst_addr; static struct class *dma_class;
static int dma_ok;
#define MEM_COPY_NO_DMA 0
#define MEM_COPY_BY_DMA 1
static DECLARE_WAIT_QUEUE_HEAD(dma_waitq); struct dma_regs {
unsigned long disrc;
unsigned long disrcc;
unsigned long didst;
unsigned long didstc;
unsigned long dcon;
unsigned long dstat;
unsigned long dcsrc;
unsigned long dcdst;
unsigned long dmasktrig;
}; static volatile struct dma_regs *dma_regs; long dma_ioctl(struct file *file, unsigned int cmd, unsigned long dat)
{
int i;
memset(src_addr,0xaa,BUFF_SIZE); //从src开始的BUFF_SIZE空间每个字节都设置为0xaa
memset(dst_addr,0x55,BUFF_SIZE); if(cmd == MEM_COPY_NO_DMA){
for(i = ; i < BUFF_SIZE; i++){
dst_addr[i] = src_addr[i];
}
if( == memcmp(src_addr,dst_addr,BUFF_SIZE)){
printk("no dma transfer has finished!\n");
}else{
printk("no dma transfer failed!\n");
}
}else if(cmd == MEM_COPY_BY_DMA){ dma_ok = ; dma_regs->disrc = psrc_addr;
dma_regs->didst = pdst_addr;
dma_regs->dcon = (<<) | (<<) | (<<) | (BUFF_SIZE); //启动DMA
dma_regs->dmasktrig = (<<) | (<<); /*等待DMA传输完成*/
wait_event_interruptible(dma_waitq, dma_ok); if( == memcmp(src_addr,dst_addr,BUFF_SIZE)){
printk("dma transfer has finished!\n");
}else{
printk("dma transfer failed!\n");
} }
return ;
} ssize_t dma_read(struct file *file, char __user *buff, size_t size, loff_t *loff)
{
int err;
err = copy_to_user(buff,dst_addr,size);
if(err){
return -;
}
return ;
} static struct file_operations dma_fop = {
.owner = THIS_MODULE,
.read = dma_read,
.unlocked_ioctl = dma_ioctl,
}; irqreturn_t dma_irq(int irq, void *devid)
{
dma_ok = ;
wake_up_interruptible(&dma_waitq);
return IRQ_HANDLED;
} static int dma_drv_init(void)
{ dma_regs = ioremap(DMA_BASE,sizeof(struct dma_regs)); src_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &psrc_addr,GFP_KERNEL);
dst_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &pdst_addr,GFP_KERNEL); if(request_irq(IRQ_DMA0,dma_irq,,"dma_irq",NULL)){
printk("request dma irq failed!\n");
free_irq(IRQ_DMA0,NULL);
return -;
} major = register_chrdev(, "dma-z", &dma_fop);
dma_class = class_create(THIS_MODULE, "DMA");
device_create(dma_class, NULL, MKDEV(major,), NULL, "dma0"); return ;
} static void dma_drv_exit(void)
{
device_destroy(dma_class,MKDEV(major,));
class_destroy(dma_class);
free_irq(IRQ_DMA0,NULL);
dma_free_writecombine(NULL, BUFF_SIZE,src_addr,psrc_addr);
dma_free_writecombine(NULL, BUFF_SIZE,dst_addr,pdst_addr);
iounmap(dma_regs);
} module_init(dma_drv_init);
module_exit(dma_drv_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("1653699780@qq.com");
linux3.4.2之DMA驱动完整程序的更多相关文章
- linux3.4.2之dma驱动
1. 分配源地址.目的地址 src_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &psrc_addr,GFP_KERNEL); dst_addr ...
- 二十二、DMA驱动
一.DMA简介 DMA(Direct Memory Access,直接内存存取),DMA传输将数据从一个地址空间复制到另外一个地址空间.传输过程由DMA控制器独立完成,它并没有拖延CPU的工作,可以让 ...
- ZYNQ DMA驱动及测试分析
之前没有接触过DMA驱动.不了解它的原理,稍作学习先总结下dma驱动步骤: 1. 申请DMA中断. 2. 申请内存空间作为src和dts的空间. 3. 注册设备注册节点 4. 将申请到的src和dst ...
- linux3.4.2之块设备驱动完整程序
/*参考drivers/block/xd.c *以及drivers/block/z2ram.c */ #include <linux/module.h> #include <linu ...
- 32.Linux-2440下的DMA驱动(详解)
DMA(Direct Memory Access) 即直接存储器访问, DMA 传输方式无需 CPU 直接控制传输,通过硬件为 RAM .I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大 ...
- S3C2440 DMA 驱动示例
将 DMA 抽象为一个字符设备,在初始化函数中调用 void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t * ...
- DMA驱动框架
框架入口源文件:dma.c (可根据入口源文件,再按着框架到内核走一遍) 内核版本:linux_2.6.22.6 硬件平台:JZ2440 以下是驱动框架: 以下是驱动代码 dma.c : #i ...
- 基于S3C2440的linux-3.6.6移植——LED驱动【转】
本文转载自:http://www.voidcn.com/blog/lqxandroid2012/article/p-625005.html 目前的linux版本的许多驱动都是基于设备模型,LED也不例 ...
- Thinkpad E430+CentOS 6.4+ linux-3.10.12内核网卡驱动(无线+有线)配置
配置并编译安装内核模块和内核后,解压附件 firmware.tar.bz2,拷贝其中的rtlwifi文件夹到/lib/firmware下,然后 执行装载内核模块命令: sudo modprobe rt ...
随机推荐
- Linux内核收包过程
net/core/dev.c int __init net_dev_init(void) { queue->backlog.poll = process_backlog; open_softir ...
- Oracle RAC和SCAN同时对外提供服务的配制方法
1, tnsnames.ora on two nodes:RACTEST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = racsca ...
- hdu 5971 Wrestling Match
题目链接: hdu 5971 Wrestling Match 题意:N个选手,M场比赛,已知x个好人,y个坏人,问能否将选手划分成好人和坏人两个阵营,保证每场比赛必有一个好人和一个坏人参加. 题解:d ...
- 阶&原根
求阶的方法: 根据性质2,直接对ϕ(m)求出因子即可,从小到大依次判断是不是符合ad = 1(mod m)(d是ϕ(m)的因子) 求最小的原根的方法: 根据性质8,对ϕ(m)求出素因子,从1开始不断测 ...
- 如何删除Word 2010中的“向下箭头”
原文:https://jingyan.baidu.com/article/e75aca85552916142edac614.html 在日常办公中,如果从网站复制了一段文字,直接粘贴到Word中时,常 ...
- LRU缓存算法与pylru
这篇写的略为纠结,算法原理.库都是现成的,我就调用了几个函数而已,这有啥好写的?不过想了想,还是可以介绍一下LRU算法的原理及简单的用法. LRU(Least Recently Used,最近最少 ...
- hdu 3068 最长回文_Manacher模板
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/neng18/article/details/24269469 pid=3068" rel= ...
- CentOS下go 安装
go 语言源码安装依赖 ,gcc ,make glibc库,等,上述工具安装省略,另外,其源代码更新采用的是mercurial 工具,安装前先安装mercureal : 1.mercurial安 ...
- mxnet导入图像数据
图像的标签在一个json文件中. %matplotlib inline import json import gluonbook as gb import mxnet as mx from mxnet ...
- JDBC(6)事务处理&批量处理
事务处理就是当执行多个SQL指令,因某个指令有误,则取消执行所有的命令 它的作用是保证各项的完整性和一致性 JDBC的数据操作时 commit():提交事务 rollback():回退事务 绝位于ja ...