博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux3.4.2之DMA驱动完整程序
阅读量:4923 次
发布时间:2019-06-11

本文共 3546 字,大约阅读时间需要 11 分钟。

1 /*  2 *参考arch/arm/mach-s3c24xx/dma-s3c2410.c  3 */  4 #include 
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 22 #define DMA_BASE 0x4b000000 23 #define BUFF_SIZE 512 24 25 static unsigned char *src_addr;//源 26 static unsigned char *dst_addr;//目的 27 static int major; 28 static dma_addr_t psrc_addr; 29 static dma_addr_t pdst_addr; 30 31 static struct class *dma_class; 32 static int dma_ok; 33 #define MEM_COPY_NO_DMA 0 34 #define MEM_COPY_BY_DMA 1 35 static DECLARE_WAIT_QUEUE_HEAD(dma_waitq); 36 37 struct dma_regs { 38 unsigned long disrc; 39 unsigned long disrcc; 40 unsigned long didst; 41 unsigned long didstc; 42 unsigned long dcon; 43 unsigned long dstat; 44 unsigned long dcsrc; 45 unsigned long dcdst; 46 unsigned long dmasktrig; 47 }; 48 49 static volatile struct dma_regs *dma_regs; 50 51 long dma_ioctl(struct file *file, unsigned int cmd, unsigned long dat) 52 { 53 int i; 54 memset(src_addr,0xaa,BUFF_SIZE); //从src开始的BUFF_SIZE空间每个字节都设置为0xaa 55 memset(dst_addr,0x55,BUFF_SIZE); 56 57 if(cmd == MEM_COPY_NO_DMA){ 58 for(i = 0; i < BUFF_SIZE; i++){ 59 dst_addr[i] = src_addr[i]; 60 } 61 if(0 == memcmp(src_addr,dst_addr,BUFF_SIZE)){ 62 printk("no dma transfer has finished!\n"); 63 }else{ 64 printk("no dma transfer failed!\n"); 65 } 66 }else if(cmd == MEM_COPY_BY_DMA){ 67 68 dma_ok = 0; 69 70 dma_regs->disrc = psrc_addr; 71 dma_regs->didst = pdst_addr; 72 dma_regs->dcon = (1<<30) | (1<<29) | (1<<27) | (BUFF_SIZE); 73 74 //启动DMA 75 dma_regs->dmasktrig = (1<<1) | (1<<0); 76 77 /*等待DMA传输完成*/ 78 wait_event_interruptible(dma_waitq, dma_ok); 79 80 if(0 == memcmp(src_addr,dst_addr,BUFF_SIZE)){ 81 printk("dma transfer has finished!\n"); 82 }else{ 83 printk("dma transfer failed!\n"); 84 } 85 86 } 87 return 0; 88 } 89 90 ssize_t dma_read(struct file *file, char __user *buff, size_t size, loff_t *loff) 91 { 92 int err; 93 err = copy_to_user(buff,dst_addr,size); 94 if(err){ 95 return -1; 96 } 97 return 1; 98 } 99 100 static struct file_operations dma_fop = {101 .owner = THIS_MODULE,102 .read = dma_read,103 .unlocked_ioctl = dma_ioctl,104 };105 106 irqreturn_t dma_irq(int irq, void *devid)107 {108 dma_ok = 1;109 wake_up_interruptible(&dma_waitq);110 return IRQ_HANDLED;111 }112 113 static int dma_drv_init(void)114 {115 116 dma_regs = ioremap(DMA_BASE,sizeof(struct dma_regs));117 118 src_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &psrc_addr,GFP_KERNEL);119 dst_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &pdst_addr,GFP_KERNEL);120 121 if(request_irq(IRQ_DMA0,dma_irq,0,"dma_irq",NULL)){122 printk("request dma irq failed!\n");123 free_irq(IRQ_DMA0,NULL);124 return -1;125 }126 127 major = register_chrdev(0, "dma-z", &dma_fop);128 dma_class = class_create(THIS_MODULE, "DMA");129 device_create(dma_class, NULL, MKDEV(major,0), NULL, "dma0");130 131 return 0;132 }133 134 static void dma_drv_exit(void)135 {136 device_destroy(dma_class,MKDEV(major,0));137 class_destroy(dma_class);138 free_irq(IRQ_DMA0,NULL);139 dma_free_writecombine(NULL, BUFF_SIZE,src_addr,psrc_addr);140 dma_free_writecombine(NULL, BUFF_SIZE,dst_addr,pdst_addr);141 iounmap(dma_regs);142 }143 144 module_init(dma_drv_init);145 module_exit(dma_drv_exit);146 147 MODULE_LICENSE("GPL");148 MODULE_AUTHOR("1653699780@qq.com");

 

转载于:https://www.cnblogs.com/zhu-g5may/p/9314819.html

你可能感兴趣的文章
C#开源项目大全
查看>>
docker 小技巧 docker network create br-name 指定IP地址
查看>>
decode函数
查看>>
通过jvm 查看死锁
查看>>
多线程(大量密集的I/O处理);多进程(大量密集并行计算);Scrapy(异步,协程)...
查看>>
rabbitmq route
查看>>
恢复为TrustedInstaller权限
查看>>
怎样利用细碎时间达到整体学习的效果
查看>>
C# 位数组
查看>>
当递归遇到synchronized
查看>>
HDU - 2141 : Can you find it?
查看>>
bzoj1093 [ZJOI2007]最大半联通子图 缩点 + 拓扑序
查看>>
《Java并发编程的艺术》之线程池(二)
查看>>
SCP注意事项
查看>>
英国NHS
查看>>
ScrollView嵌套GridView和ListView行高问题
查看>>
测试秒杀新版本3.5 stieserver cms
查看>>
Lua获取当前时间
查看>>
自己关于ES6的一点理解
查看>>
Python(32bit)运行报错:MemoryError
查看>>