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 ...
随机推荐
- 立即终止Sleep的线程
在实际工作中,我们需要每隔几分钟从API取数. while(isRunning) { work(); Thread.Sleep(5*60*1000); } 如果设置isRunning=false,也需 ...
- cocos2d-x 3.1 编译脚本android-build.py
写在前面: 前段时间下载了cocos2d-x 3.1,按照官网的教程,配置环境,编译打包,走了一遍,感觉不错,顺便发现其中用了很多python的脚本文件,比如今天要说的android-build.py ...
- 看了xici有写给孩子的信,maybe我也要写给孩子一些东西了
看了xici有写给孩子的信,maybe我也要写给孩子一些东西了
- Posix多线程编程学习笔记
Blaise Barney, Lawrence Livermore National Laboratory )标准制订了这一标准接口.依赖于该标准的实现就称为POSIX threads 或者Pthre ...
- 跳跃表 SkipList【数据结构】原理及实现
为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等. 想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树出来吗? ...
- Java使用iText生成word文件的完美解决方案(亲测可行)
JAVA生成WORD文件的方法目前有以下种: 一种是jacob 但是局限于windows平台 往往许多JAVA程序运行于其他操作系统 在此不讨论该方案 一种是pio但是他的excel处理很程序 wor ...
- codeforces793 B. Igor and his way to work (dfs)
题目链接:codeforces793 B. Igor and his way to work (dfs) 求从起点到终点转方向不超过两次是否有解,,好水啊,感觉自己代码好搓.. #include< ...
- java的串行化
参考博客:Java 对象的串行化(Serialization) 1,什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象 ...
- bzoj3106 [cqoi2013]棋盘游戏
Description 一个n*n(n>=2)棋盘上有黑白棋子各一枚.游戏者A和B轮流移动棋子,A先走. l A的移动规则:只能移动白棋子.可以往上下左右四个方向之一移动一格. ...
- Pollard_rho 因数分解
Int64以内Rabin-Miller强伪素数测试和Pollard 因数分解的算法实现 选取随机数\(a\) 随机数\(b\),检查\(gcd(a - b, n)\)是否大于1,若大于1则\(a - ...