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 ...
随机推荐
- Python初学者第一天 Python安装及第一个Python程序
Python基础: 1day: 1.Python基础: A.编程语言介绍: a. 计算机只能理解0和1.编程即写一段按照一定规则写代码,让计算机帮你干活: b.机器语言:最底层的语言, ...
- 在IIS7上导出所有应用程序池的方法 批量域名绑定
在IIS7+上导出所有应用程序池的方法:%windir%/system32/inetsrv/appcmd list apppool /config /xml > c:/apppools.xml ...
- Oracle中的rownum不能使用大于>的问题
标题:Oracle中的rownum不能使用大于>的问题 一.对rownum的说明 关于Oracle 的 rownum 问题,很多资料都说不支持SQL语句中的“>.>=.=.betwe ...
- 【[USACO08FEB]酒店Hotel】
比较基础的线段树了 我们要维护最大连续子串,这个可以说是一个比较套路的操作了 我们在[SHOI2009]会场预约这道题中已经比较深刻的认识到了这个套路了 对于这道题,我们显然要知道一个区间内最大的全为 ...
- rc.local 开机自启脚本无法启动
1.看是否rc.local 第一行如果是 #!/bin/sh -e 改成 #!/bin/bash sudo systemctl enable rc-local.service 2.看rc.local的 ...
- PHP-------抽象和接口
静态的关键字是:static Class ren { Public static $yanse; //yanse是一个静态的成员 Static function show() ; // stat ...
- java的foreach,后台弹框
for (String string : list) { if(string.equals(ids)){ int res = JOptionPane.showConfirmDialog(null, & ...
- Apple的UIAutomation环境搭建和入门知识
简述 Xcode的instruments中的Automation是为了实现自动化测试的一个工具.实现方式有两种:它提供了两种实现方式, 1) 是通过JS脚本语言来执行自动化测试(普通自动化测试 ...
- STM32F10X固件库函数——串口清状态位函数分析
STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...
- Before start of result set
ResultSet:在处理结果集的时候出现了问题. 解决办法:while(rs.next())