Linux下DMA驱动框架分析

linux下的DMA驱动框架drivers\dma\dmaengine.c文件内,在linux下编写DMA的设备驱动一般步骤如下。


  1. 申请DMA通道

    struct dma_chan *dma_request_channel(dma_cap_mask_t mask,

    dma_filter_fn filter_fn,

    void *filter_param);

     

    其中dma_cap_mase_t是根据dma_cap_sets指定的DMA传输类型;filter_param是外设ID。如:

                 dma_cap_mask_t mask;

    dma_cap_zero(mask);

             dma_cap_set(DMA_MEMCPY,mask);

                 dma_chan1 = dma_request_channel(mask,0,NULL);

  2. DMA通道的配置

    int dmaengine_slave_config(struct dma_chan *chan, struct dma_slave_config *config);

    可以通过config结构体设置DMA通道宽度、数据传输宽带、源地址目的地址等信息。

  3. 获得传输描述符

    通过device_prep_slave_sg() 或者

           device_prep_dma_cyclic() 或者

           device_prep_dma_memcpy() 获取desc,再将回调函数指针穿给desc->callback。

  4. 提交传输

    调用dmaengine_submit((struct dma_async_tx_descriptor *)desc),将desc提交到DMA等待队列。

  5. 启动传输

    dmaengine_issue_pending调用会从第一个描述符开始进行传输。如果DMA 设备驱动有回调函数的话,会在传输完成后执行。

     

    下面介绍一下获得传输描述符的三种方式。

    device_prep_dma_memcpy(),明显是DMA内存到内存的拷贝

    有些DMA支持分散集合模式,即内存中数据并非连续,这中情况可以调用通过device_prep_slave_sg函数进行传输,描述符是一个单向列表,描述了每块数据的位置和大小还有其他配置。DMA自行解析描述符的内容进行数据传输并寻找下一个链表节点。

     

    如果是循环连接,则传输被叫做循环传输,需要用到device_prep_dma_cyclic()函数进行传输,例如linux下的串口驱动,它的传输buffer是一个环形缓冲区,它用DMA传输时就采用了循环传输方式。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值