• S3C2440 DMA 驱动示例


    将 DMA 抽象为一个字符设备,在初始化函数中调用

    void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
    

    函数来分配两段物理地址连续的空间,一段作为源空间,一段作为目的空间。

    然后将物理地址进行 ioremap 供驱动使用,最后调用 register_chrdev 来注册这个字符设备。

    DMA 的 regs:

    #define DMA0_BASE_ADDR  0x4B000000
    #define DMA1_BASE_ADDR  0x4B000040
    #define DMA2_BASE_ADDR  0x4B000080
    #define DMA3_BASE_ADDR  0x4B0000C0
    
    struct s3c_dma_regs {
    	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 dmasktrig;
    };
    

    配置 DMA(通过 ioctl 调用)

        ev_dma = 0;
    
        /* 把源,目的,长度告诉 DMA */
        dma_regs->disrc      = src_phys;            /* 源的物理地址 */
        dma_regs->disrcc     = (0<<1) | (0<<0);     /* 源位于 AHB 总线, 源地址递增 */
        dma_regs->didst      = dst_phys;            /* 目的的物理地址 */
        dma_regs->didstc     = (0<<2) | (0<<1) | (0<<0);     /* 目的位于 AHB 总线, 目的地址递增 */
        dma_regs->dcon       = (1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(0<<20)|(BUF_SIZE<<0);  /* 使能中断,单个传输,软件触发, */
        
        /* 启动 DMA */
        dma_regs->dmasktrig  = (1<<1) | (1<<0);
        
        /* 如何知道 DMA 什么时候完成 ? */
        /* 休眠 */
        wait_event_interruptible(dma_waitq, ev_dma);
        
        if (memcmp(src, dst, BUF_SIZE) == 0)
        {
        	printk("MEM_CPY_DMA OK
    ");
        }
        else
        {
        	printk("MEM_CPY_DMA ERROR
    ");
        }
    

    当 DMA 开始工作时会休眠一段时间,直到复制完成后触发中断来唤醒。

    static irqreturn_t s3c_dma_irq(int irq, void *devid)
    {
    	/* 唤醒 */
    	ev_dma = 1;
        wake_up_interruptible(&dma_waitq);   /* 唤醒休眠的进程 */
    	return IRQ_HANDLED;
    }
    

    可能这样的实验并不会看出 DMA 的作用,我们可以与普通的复制做一下速度上的对比。例如用 memcpy 来与 DMA PK 一下速度就能看出效果来。

  • 相关阅读:
    [转]SQLSERVER 18056 错误
    【转】 Windows控制台上的UTF8支持
    无法访问共享解决方案之一
    performselectoronmainthread
    iphone开发多线程
    iPad app应用开发系列文章之三 -- iOS的多核编程和内存管理
    ObjectiveC中一种消息处理方法performSelector: withObject:
    UIView你知道多少
    NSBundle介绍
    Blocks,注意
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/8552582.html
Copyright © 2020-2023  润新知