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 ...
随机推荐
- easyui的解析器Parser
平时使用easyui做框架开发时,都知道easyui的模块组件能通过属性方法或js方法来渲染,本质上是通过parser解析器来处理实现的,因为多数情况下都是自动触发完成整个页面的解析,所以没有感觉到它 ...
- T-SQL语法学习一(持续更新)
T-SQL语法学习(一) 第一节 不常用语句 不常用语句-指的是一些不常用的查询语句,不针对业务数据查询 SET STATISTICS IO ON(用于查询逻辑读取次数,物理读取次数) 图片 sele ...
- Oracle案例07——ORA-28000: the account is locked
遇到这个错误,一般我们想到的是数据库用户被锁,只需要执行用户解锁即可恢复,但这里之所以写出来是因为比较奇葩的一个问题. 昨天下午接同事信息,说一个用户连接报被锁,经过沟通发现其实连接一个ADG的备库作 ...
- docker初使用(主要记录命令)
启动服务 docker run -it -p : steveny/predictionio: /bin/bash 开始所有服务 pio-start-all 查看有那些服务 jps -l $ docke ...
- MQ--API总结
研究MQ很长时间了, 每个类,方法,都查了很长时间,在此总结一下! Java编写访问MQ的程序 1.MQQueueManager―――队列管理器访问类 常用方法: public MQQueueMan ...
- JDK工具系列之jps
一.简介 jps(JVM Process Status Tool)是虚拟机进程状态工具:可以列出正在运行的虚拟机进程,显示虚拟机正在执行的main()函数,及这些进程的ID(LVMID,Local V ...
- 三·管理和配置Subversion(基于Centos7)
基于上一篇文章 二·安装Subversion(基于Centos7)中安装的Subversion,本篇文章讲述Subversion的管理和配置 1.添加环境变量 输入命令vi /etc/profile ...
- CentOS下go 安装
go 语言源码安装依赖 ,gcc ,make glibc库,等,上述工具安装省略,另外,其源代码更新采用的是mercurial 工具,安装前先安装mercureal : 1.mercurial安 ...
- PHP---练习-----留言板
题目::留言显示 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- 在thinkphp5.0中调用ajax时, 返回的JSON 格式数据在html前台不能用时
在thinkphp5.0中调用ajax时,如果控制器返回的数据为json格式,视图层接收到返回值即为json格式的数据,此时应该把 JSON 文本转换为 JavaScript 对象,方便调用.具体代码 ...