DMA驱动框架
框架入口源文件:dma.c
(可根据入口源文件,再按着框架到内核走一遍)
内核版本:linux_2.6.22.6 硬件平台:JZ2440
以下是驱动框架:
以下是驱动代码 dma.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 <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>
#include <linux/dma-mapping.h> //源地址
static unsigned char *src;
static unsigned int src_phy; //目的地址
static unsigned char* dest;
static unsigned int dest_phy; //空间大小
#define DMA_SIZE (1204*512) //驱动类
static struct class *dma_class; //主设备号
static int major ; #define USE_DMA 1
#define NO_DMA 0 //DMA寄存器
static struct s3c_dma_reg
{
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 dmaskting;
}*s3c_dma_regs; //DMA地址
static unsigned long dma_addr0 = 0x4b000000;
static unsigned long dma_addr1 = 0x4b000040;
static unsigned long dma_addr2 = 0x4b000080;
static unsigned long dma_addr3 = 0x4b0000c0; //为这个进程创建等待队列
static DECLARE_WAIT_QUEUE_HEAD(dma_wait_queue); //进程队列标志位
static volatile int dma_wait_queue_condition=; static int s3c_dma_iotcl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long args)
{
int i=;
memset(src, 0xAA, DMA_SIZE);
memset(dest, 0x55, DMA_SIZE); switch(cmd)
{
case NO_DMA :
{
for(i=;i<DMA_SIZE;i++) dest[i] = src[i];
if(memcmp(src,dest,DMA_SIZE) == ) printk("copy without DMA successfuly !\n");
else printk("copy without DMA fialed !\n");
break;
}
case USE_DMA :
{
// 设置DMA寄存器
s3c_dma_regs->disrc = src_phy;
s3c_dma_regs->disrcc = (<<)|(<<);
s3c_dma_regs->didst = dest_phy;
s3c_dma_regs->didstc =(<<)|(<<)|(<<);
s3c_dma_regs->dcon = (<<)|(<<)|(<<)|(<<)|(<<)|(<<)|(DMA_SIZE<<);
s3c_dma_regs->dmaskting = (<<)|(<<); //休眠进程
dma_wait_queue_condition = ; //状态标志位为假 休眠dma.c进程 。 进程可被信号中断休眠,返回非0值表示休眠被信号中断
wait_event_interruptible(dma_wait_queue, dma_wait_queue_condition); if(memcmp(src,dest,DMA_SIZE) == ) printk(" copy with DMA successfuly !\n");
else printk("copy with DMA failed !\n");
break;
}
}
return ; } //字符设备操作函数
static struct file_operations dma_fops =
{
.owner = THIS_MODULE,
.ioctl = s3c_dma_iotcl,
}; //中断处理函数
static int s3c_dma_irq(int irq, void *devid)
{
dma_wait_queue_condition = ; //状态为真 唤醒dma.c进程
wake_up_interruptible(&dma_wait_queue);
return IRQ_HANDLED;
} static int dma_init(void)
{
//申请中断
request_irq(IRQ_DMA3, s3c_dma_irq,, "s3c_dma", ); //申请源地址空间
src = dma_alloc_writecombine(NULL,DMA_SIZE, &src_phy,GFP_KERNEL);
//申请目的地址空间
dest= dma_alloc_writecombine(NULL,DMA_SIZE, &dest_phy,GFP_KERNEL); //dma_reg映射
s3c_dma_regs = ioremap(dma_addr3,sizeof(struct s3c_dma_reg)); //注册字符设备
major = register_chrdev(, "s3c_dma",&dma_fops); //注册类 设备节点 dma_class = class_create(THIS_MODULE,"s3c_dma_class"); // /sys/class/s3c_dma_class
class_device_create(dma_class,NULL,MKDEV(major,),NULL, "s3c_dma"); // /dev/s3c_dma return ;
} static void dma_exit(void) {
free_irq(IRQ_DMA3,);
dma_free_writecombine(NULL,DMA_SIZE, src,GFP_KERNEL);
dma_free_writecombine(NULL,DMA_SIZE, dest,GFP_KERNEL);
iounmap(s3c_dma_regs);
unregister_chrdev(major, "s3c_dma");
class_destroy(dma_class);
class_device_destroy( dma_class,MKDEV(major,));
} module_init(dma_init);
module_exit(dma_exit); MODULE_LICENSE("GPL");
以下是驱动测试文件:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h> #define USE_DMA 1
#define NO_DMA 0 int main(int argc ,char **argv)
{
int fd=;
fd = open("/dev/s3c_dma", O_RDWR);
if(fd<) printf("can't open \n");
if(argc !=) printf("please using like this : ./dma_test <dma|no_dma>\n"); if(argc ==)
{
if(strcmp(argv[],"dma")==) while() ioctl(fd,USE_DMA);
if(strcmp(argv[],"no_dma")==)while() ioctl(fd,NO_DMA);
} return ;
}
以下是编译驱动的Makefile:
KERN_DIR = /work/systems/kernel/linux-/linux-2.6.22.6 all:
make -C $(KERN_DIR) M=`pwd` modules clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order obj-m +=dma.o
DMA驱动框架的更多相关文章
- 二十二、DMA驱动
一.DMA简介 DMA(Direct Memory Access,直接内存存取),DMA传输将数据从一个地址空间复制到另外一个地址空间.传输过程由DMA控制器独立完成,它并没有拖延CPU的工作,可以让 ...
- 基于Linux 3.0.8 Samsung FIMC(S5PV210) 的摄像头驱动框架解读(一)
作者:咕唧咕唧liukun321 来自:http://blog.csdn.net/liukun321 FIMC这个名字应该是从S5PC1x0開始出现的.在s5pv210里面的定义是摄像头接口.可是它相 ...
- Linux设备驱动框架设计
引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Li ...
- lcd驱动框架
目录 lcd驱动框架 框图 程序分析 入口 打开open 读read 初始化registered_fb 注册 小结 程序设计 测试 方式一操作fb0 方式二操作tty 方式三操作终端 完整程序 tit ...
- Linux USB驱动框架分析(2)【转】
转自:http://blog.chinaunix.net/uid-23046336-id-3243543.html 看了http://blog.chinaunix.net/uid-11848011 ...
- Linux USB驱动框架分析 【转】
转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...
- 2.1 摄像头V4L2驱动框架分析
学习目标:学习V4L2(V4L2:vidio for linux version 2)摄像头驱动框架,分析vivi.c(虚拟视频硬件相关)驱动源码程序,总结V4L2硬件相关的驱动的步骤: 一.V4L ...
- Linux下USB驱动框架分析【转】
转自:http://blog.csdn.net/brucexu1978/article/details/17583407 版权声明:本文为博主原创文章,未经博主允许不得转载. http://www.c ...
- Linux USB驱动框架分析【转】
转自:http://blog.csdn.net/jeffade/article/details/7701431 Linux USB驱动框架分析(一) 初次接触和OS相关的设备驱动编写,感觉还挺有意思的 ...
随机推荐
- rabbitmq启动异常table_attributes_mismatch
rabbitmq启动异常table_attributes_mismatch 2017年01月09日 16:57:50 growithus 阅读数:18 [root@localhost rabb ...
- Linux+树莓派3开发总结——树莓派远程文件共享winows
http://blog.csdn.net/xqf1528399071/article/details/52192134 ———————————————————————————————————————— ...
- 执行start-dfs.sh后,datenode没有启动的解决办法
执行start-dfs.sh后,datenode没有启动,很大一部分原因是因为在第一次格式化dfs后,启动并使用了hadoop,后来又重新执行了格式化命令(hdfs namenode -format) ...
- Git -- 自定义git样式
在安装Git一节中,我们已经配置了user.name和user.email,实际上,Git还有很多可配置项. 比如,让Git显示颜色,会让命令输出看起来更醒目: $ git config --glob ...
- 【QT】无需写connect代码关联信号和槽函数
对于一些简单的事件判别,如点击按钮. 无需写代码关联信号和槽函数. connect(ui->Btnshowhello,SIGNAL(clicked(bool)),this,SLOT(Btnsho ...
- 【代码审计】大米CMS_V5.5.3 后台多处存储型XSS漏洞分析
0x00 环境准备 大米CMS官网:http://www.damicms.com 网站源码版本:大米CMS_V5.5.3试用版(更新时间:2017-04-15) 程序源码下载:http://www ...
- MapReduce处理HBase出错:XXX.jar is not a valid DFS filename
原因:Hadoop文件系统没有检查路径时没有区分是本地windows系统还是Hadoop集群文件系统 解决: 只需将Map和Reduce的init方法最后一个参数(boolean addDepend ...
- day_5.27python网络编程
开始进行python网络编程2018-5-27 20:27:30 Tcp/Ip协议
- Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
说明:这里没练习静态自动验证:如果用到静态验证首先自定义一个控制器,再在Model文件夹里创建一个NiHaoModel.php 类 NiHao是自定义的,前缀可以随意,但是一定要用驼峰法(首字母大写 ...
- PHP数组(数组正则表达式、数组、预定义数组)
正则表达式 1.替换 $s = "hello5world"; $s = preg_replace("/\d/","#",$s); echo ...