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 ...
随机推荐
- tpcc-mysql安装测试与使用生成对比图
1:下载tpcc-mysql的压缩包,从下面的网站进行下载 https://github.com/Percona-Lab/tpcc-mysql 也可直接从叶总博客直接下载: http://imysql ...
- java.langThrowable:STACKTRACE
Jboss版本是4.2.0.GA代码运行完后总报错 但是程序的运行结果没问题 请问下这是什么原因2009-12-11 01:53:26,611 INFO [org.jboss.resource.co ...
- 一道算法题-从1到n整数中1出现的次数
1. 题目描述 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次. 2. 题目来源 第一次看到是在 ...
- eigenMatrix
#include <iostream> using namespace std; #include <ctime> // Eigen 部分 #include <Eigen ...
- ZT 七大寡头
网易评论人才辈出啊!!!看下面 http://comment.news.163.com/news_guoji2_bbs/9GRIIJA90001121M.html 关注 关注他的微博yftyfm ...
- boost::intrusive_ptr原理介绍
boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intru ...
- 「C语言」在Windows平台搭建C语言开发环境的多种方式
新接触C语言,如何在Windows下进行C语言开发环境的搭建值得思考并整理. 以下多种开发方式择一即可(DEV C++无须环境准备). 注:本文知识来源于 Windows 平台搭建C语言集成开发环境 ...
- phoneGap的Android下编写phonegap 插件
一. javascript 端的编写 第一个参数 成功的回调函数 第二个参数 失败的回调函数 第三个参数 是插件的类名称,也就是后台java文件的类名 第四个参数 执行的 action 名称 ...
- 【CSS】易错
1.外边距默认是透明的,因此不会遮挡其后的任何元素.2.背景应用于由内容和内边距.边框组成的区域.3.外边距可以是负值,而且在很多情况下都要使用负值的外边距.4.不要给元素添加具有指定宽度的内边距,而 ...
- 浅谈sql之连接查询
SQL之连接查询 一.连接查询的分类 sql中将连接查询分成四类: 内链接 外连接 左外连接 右外连接 自然连接 交叉连接 二.连接查询的分类 数据库表如下: 1.学生表 2.老师表 3.班级表 表用 ...