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相关的设备驱动编写,感觉还挺有意思的 ...
随机推荐
- java二叉树字典查询(qq 928900200)
This assignment will help you practice and understand better the Binary Tree and Binary Search Tree ...
- 说说自己对RESTful API的理解
REST不是英文上的rest单词,其英文缩写为presentational State Transfer ,直译为表现状态转移,咋看起来很学术,不懂,其实不用去死抠这个词的意思.REST是一种约束和架 ...
- Mac mysql 修改密码
如果你知道密码: mysqladmin -u root -p password 新密码 MYSQL数据库密码忘记: 1. 在系统偏好 中,中止MYSQL服务.: 2. cd/usr/local/mys ...
- 利用Backtrace来捕获段错误堆栈信息
具体参考文档:https://blog.csdn.net/gatieme/article/details/84189280 测试Demo: #include <execinfo.h> #i ...
- SpringBatch的流程简介
SpringBatch的流程图如下: 每个Batch都会包含一个Job.Job就像一个容器,这个容器装了若干Step,Batch中实际干活的也就是这些Step,至于Step干什么活,无外乎读取数据,处 ...
- 如何获取控件id,包名,类名
- Linux Platform驱动模型(三) _platform+cdev
平台总线是一种实现设备信息与驱动方法相分离的方法,利用这种方法,我们可以写出一个更像样一点的字符设备驱动,即使用cdev作为接口,平台总线作为分离方式: xjkeydrv_init():模块加载函数 ...
- 洛谷P1216 数字三角形【dp】
题目:https://www.luogu.org/problemnew/show/P1216 题意: 给定一个三角形.从顶走到底,问路径上的数字之和最大是多少. 走的时候可以往左下(实际上纵坐标不变) ...
- hdu2594 Simpsons' Hidden Talents【next数组应用】
Simpsons’ Hidden Talents Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- LuoguP3834 【模板】可持久化线段树 1(主席树)|| 离散化
题目:[模板]可持久化线段树 1(主席树) 不知道说啥. #include<cstdio> #include<cstring> #include<iostream> ...