zoukankan      html  css  js  c++  java
  • linux3.4.2之DMA驱动完整程序

      1 /*
      2 *参考arch/arm/mach-s3c24xx/dma-s3c2410.c
      3 */
      4 #include <linux/module.h>
      5 #include <linux/kernel.h>
      6 #include <linux/fs.h>
      7 #include <linux/init.h>
      8 #include <linux/delay.h>
      9 #include <linux/irq.h>
     10 #include <asm/uaccess.h>
     11 #include <asm/irq.h>
     12 #include <asm/io.h>
     13 #include <linux/poll.h>
     14 #include <plat/regs-dma.h>
     15 #include <mach/dma.h>
     16 #include <plat/dma-s3c24xx.h>
     17 #include <linux/cdev.h>
     18 #include <linux/backing-dev.h>
     19 #include <linux/wait.h>
     20 #include <linux/interrupt.h>
     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!
    ");
     63           }else{
     64              printk("no dma transfer failed!
    ");
     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!
    ");
     82      }else{
     83          printk("dma transfer failed!
    ");
     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!
    ");
    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");
  • 相关阅读:
    Spring AOP总结(三)
    Spring AOP源码解析(二)
    java9新特性
    BeanFactory和ApplicationContext的区别总结
    Elasticsearch7.X为什么移除类型(type)
    elasticsearch性能优化(二)
    elasticsearch性能优化(一)
    elasticsearch的master选举机制
    自动化构建和部署应用系统平台
    关系型数据库之mysql-01
  • 原文地址:https://www.cnblogs.com/zhu-g5may/p/9314819.html
Copyright © 2011-2022 走看看