S3C2440 DMA驱动程序编写及测试(三十二)

https://www.cnblogs.com/lifexy/p/7880737.html

DMA(Direct Memory Access)

即直接存储访问,DMA传输方式无需CPU直接控制传输,通过硬件为RAM、I/O设备开辟一条直接传输数据的通路,能使CPU的效率大为提高。


学了这么多驱动,不难退出DMA的编写套路:

  • 1)注册DMA中断,分配缓冲区
  • 2)注册字符设备,并提供文件操作集合fops
  •         -> 2.1)file_operations里设置DMA硬件相关操作,来启动DMA

由于我们是用字符设备的测试方式测试的,而本例子只是用两个地址之间的拷贝来演示DMA的作用,所以采用字符设备方式编写

 

1、驱动编写之前,先来讲如何分配释放缓冲区DMA相关寄存器使用DMA中断

1.1 在linux中,分配释放DMA缓冲区,常用以下几个函数

1)dma_alloc_writecombine()函数:

/* 该函数只禁止cache缓冲,保持写缓冲区,也就是对注册的物理区写入数据,也会更新到对应的虚拟缓冲区上 */
void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
//分配DMA缓存区
//返回值为:申请到的DMA缓冲区的虚拟地址,若为NULL,表示分配失败,需要释放,避免内存泄漏
//参数如下:
    //*dev:指针,这里填0,表示这个申请的缓冲区里没有内容
    //size:分配的地址大小(字节单位)
    //*handle:申请到的物理起始地址
    //gfp:分配出来的内存参数,标志定义在<linux/gfp.h>,常用标志如下:
        //GFP_ATOMIC 用来从中断处理和进程上下文之外的其他代码中分配内存,从不休眠
        //GFP_KERNEL 内核内存的正常分配,可能睡眠
        //GFP_USER   用来为用户空间页来分配内存;它可能睡眠

2)dma_alloc_coherent()函数:

/*该函数禁止cache缓存以及禁止写入缓冲区,从而使CPU读写的地址和DMA读写的地址内容一致*/
void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);         
//分配DMA缓存区,返回值和参数和上面的函数一直

3)dma_free_writecombine()函数:

dma_free_writecombine(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle);   //释放DMA缓存,与dma_alloc_writecombine()对应
//size:释放长度
//cpu_addr:虚拟地址,
//handle:物理地址

4)dma_free_coherent()函数:

dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)    //释放DMA缓存,与dma_alloc_coherent ()对应
//size:释放长度
//cpu_addr:虚拟地址,
//handle:物理地址

(PS:dma_free_writecombine()其实就是dma_free_coherent(),只不过是用了#define重命名而已。)

而我们之前用的内存分配kmalloc()函数,是不能用在DMA上,因为分配出来的内存可能在物理地址上不连续的,因为DMA没有那么智能,不知道一会跑去那里,一会跑去那里。

 

1.2 那么2440开发板如何来启动DMA,先来看一下2440的DMA寄存器

PS:实际这些DMA相关的寄存器,在linux内核中三星公司已封装好了,可以直接调用,不过非常麻烦,还不如直接设置寄存器,可以参考:https://blog.youkuaiyun.com/mirkerson/article/details/6632273

1.2.1 2440支持4个通道的DMA控制器

其中4个DMA外设请求源,如下图所示(通过DCONn寄存器的[26:24]来设置)

PS:如果请求源是在系统总线上的,就只需要设置DCONn寄存器的[23]=0即可)

1.2.2 且每个通道都可以处理以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值