• 在linux下使用am335x的DMA


    [本文首发于cnblogs,作者:byeyear,Email:east3@163.com]

    这几天在弄am3358的DMA,简化应用环境如下:

    am3358的FSMC接了一片FPGA;

    FPGA上接ADC;

    am3358通过FPGA以DMA方式读取ADC数据。

    事先在网上查找过相关资料,发现关于这方面工作的文章极少,即使TI官网上也没什么可靠资料,心里还是有些忐忑的,结果在实现过程中发现意外的简单,所以把过程写下来,希望有相似需求的同行可以少走弯路。

    注意:阅读本文要求具备一定的linux设备驱动开发经验,如果您从没有做过linux驱动开发,那么阅读本文时可能会有一定的困难。

    文章基于TI提供的Linux SDK 3.0。

    1. 引脚配置

    引脚配置分两块:FSMC引脚配置和外部DMA请求引脚配置。这里建议大家到TI网站上下载它的pinmux工具,点点鼠标就可以生成devicetree,非常直观简单,所以就不展开讲了。

    2. 外部DMA请求形式

    在TI的处理器手册上没有找到外部DMA引脚请求形式,不过一般来说不外乎上升沿或下降沿两种,所以我偷了个懒,使用一个1us宽度的正脉冲来提交DMA请求。

    3. crossbar配置

    crossbar的配置可以参照Linux内核文档Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt。我使用了DMA Channel 58和Transfer Controller 1,所以我的devicetree文件有如下内容:

    dmas=<&edma_xbar 58 1 28>;

    TI的EDMA Engine会根据上面这行内容为你配置好crossbar,几乎不需要在你自己的驱动里做任何工作。
    4. linux下的DMA驱动程序框架

    linux DMA驱动程序框架文档位于linux内核目录树下Documentation/dmaengine,主要看client.txt就可以了。在这篇文档里说明了该如何使用DMA Engine的API。原则上来说,只要根据这篇文档所述内容编程,就可以搞定了。另外我还参考了drivers/crypto/omap-aes.c,这个驱动也使用了DMA。不过针对具体的TI DMA控制器,这里还是有一些补充说明:

    • addr_width:这个根据你外设情况设置。我的是16位ADC,所以我设置为DMA_SLAVE_BUSWIDTH_2_BYTES。
    • maxburst:这个可设置为当你提交DMA请求时的可用数据量。我的FPGA里放了一个1k的FIFO,在累积到512数据点时提交DMA请求,所以将maxburst设置为512。maxburst的单位依据addr_width设定。比如addr_width是2bytes,那么一个burst就是512个数据点,或1024字节。
    • 不同的DMA控制器需要厂家实现自己的dmaengine底层,TI的底层实现在drivers/dma/edma.c。
    • 如果你将maxburst设置为1,TI的驱动将使用A Sync方式驱动EDMA;若maxburst大于1,就使用AB Sync方式。不管是哪种方式,acnt都等于addr_width所设定的数据量。

    5. 嗯,就只有这么多了。

  • 相关阅读:
    PAT1124:Raffle for Weibo Followers
    Pat1071: Speech Patterns
    PAT1032: Sharing (25)
    Pat1128:N Queens Puzzle
    C++相关:C++的IO库
    Pat1108: Finding Average
    PAT1070:Mooncake
    乐港游戏校招面试总结
    并发编程005 --- future &&futureTask
    并发编程004 --- 线程池的使用
  • 原文地址:https://www.cnblogs.com/byeyear/p/7184178.html
Copyright © 2020-2023  润新知