框架入口源文件: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驱动框架的更多相关文章

  1. 二十二、DMA驱动

    一.DMA简介 DMA(Direct Memory Access,直接内存存取),DMA传输将数据从一个地址空间复制到另外一个地址空间.传输过程由DMA控制器独立完成,它并没有拖延CPU的工作,可以让 ...

  2. 基于Linux 3.0.8 Samsung FIMC(S5PV210) 的摄像头驱动框架解读(一)

    作者:咕唧咕唧liukun321 来自:http://blog.csdn.net/liukun321 FIMC这个名字应该是从S5PC1x0開始出现的.在s5pv210里面的定义是摄像头接口.可是它相 ...

  3. Linux设备驱动框架设计

    引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Li ...

  4. lcd驱动框架

    目录 lcd驱动框架 框图 程序分析 入口 打开open 读read 初始化registered_fb 注册 小结 程序设计 测试 方式一操作fb0 方式二操作tty 方式三操作终端 完整程序 tit ...

  5. Linux USB驱动框架分析(2)【转】

    转自:http://blog.chinaunix.net/uid-23046336-id-3243543.html   看了http://blog.chinaunix.net/uid-11848011 ...

  6. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  7. 2.1 摄像头V4L2驱动框架分析

    学习目标:学习V4L2(V4L2:vidio for linux version 2)摄像头驱动框架,分析vivi.c(虚拟视频硬件相关)驱动源码程序,总结V4L2硬件相关的驱动的步骤:  一.V4L ...

  8. Linux下USB驱动框架分析【转】

    转自:http://blog.csdn.net/brucexu1978/article/details/17583407 版权声明:本文为博主原创文章,未经博主允许不得转载. http://www.c ...

  9. Linux USB驱动框架分析【转】

    转自:http://blog.csdn.net/jeffade/article/details/7701431 Linux USB驱动框架分析(一) 初次接触和OS相关的设备驱动编写,感觉还挺有意思的 ...

随机推荐

  1. android开发(47) 使用xml drawable 实现 局部圆角,可用作圆角边框

    代码如下: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android=" ...

  2. Java知多少(47)多重catch语句的使用

    某些情况,由单个代码段可能引起多个异常.处理这种情况,你可以定义两个或更多的catch子句,每个子句捕获一种类型的异常.当异常被引发时,每一个catch子句被依次检查,第一个匹配异常类型的子句执行.当 ...

  3. C++ 智能指针六

    /* 智能指针unique_ptr */ #include <iostream> #include <string> #include <memory> #incl ...

  4. 【转】xhEditor技术手册 网页编辑器基础教程

    1. xhEditor入门基础 1.1. 在线可视化HTML编辑器概述1.2. 获取xhEditor1.3. xhEditor运行环境1.4. xhEditor基本使用指南 1.1. 在线可视化HTM ...

  5. mysql语法 -- concat函数

    mysql CONCAT(str1,str2,…)                        返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL.或许有一个或多个参 ...

  6. 【netcore基础】.NET Core使用EPPlus实现MVC API里的Excel导出功能 配置中文表头

    EPPlus 用来操作excel非常方便,不用依赖微软的office包,所以推荐使用. 下面是具体步骤和代码 首先用nuget安装 EPPlus.Core 我装的版本是 1.5.4 然后就可以用 Ex ...

  7. 返回一个数组升序排列后的位置信息--C#程序举例

    返回一个数组升序排列后的位置信息--C#程序举例 返回某一个数组升序排序后的位置  比如:{8,10,9,11}排序后应该是{8,9,10,11},但是需要返回{1,3,2,4}   大概记忆里是这么 ...

  8. Python中通过lambda抛异常的奇技淫巧

    假设我们需要一个函数什么事都不干,只是抛出异常(在某些系统中有些handler就是干这事的),我们可以很直观的写出下面的代码: def func(): raise Exception("th ...

  9. Linux下makefile学习

    [make是什么?] make是一个命令工具,是一个解释makefile中指令的命令工具.它可以简化编译过程里面所下达的指令,当执行 make 时,make 会在当前的目录下搜寻 Makefile ( ...

  10. J - 哈密顿绕行世界问题

    一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行 ...