DMA子是CPU中实现数据传输的一种方式,CPU配置好DMA控制器之后发起数据传输,CPU本身不参与数据传输的动作中去。
DMA种类:
分为外设DMA和DMA控制器。其中外设DMA实现的为特定的外设与内存之间的数据传输,一般是外设向RAM单向传输数据。而DMA控制器则可以实现任意外设与内存之间的数据传输。此时外设跟CPU控制器之间通过流控制信号来保证传输通道的正常运行。
DMA传输的数据宽度不固定。
还可以实现任意长度的burst 操作。burst是DMA控制地址总线自行改变。
DMA也支持分散集合模式,即内存中数据并非连续,而是分配在多个块中,块大小也不一样,这时候DMA可以根据Scatter Gather Descriptors来进行DMA数据传输。
Descriptors是一个单向列表,描述了每块数据的位置和大小还有其他配置。DMA自行解析Descriptors的内容进行数据传输并寻找小一个链表节点,
如果Descriptor 链表是一个循环链接,则传输被叫做环形传输(Cyclic Transfers)。
linux实现了DMA框架,叫做DMA Engine,内核驱动开发者必须按照固定的流程编码才能正确的使用DMA。DMA Engine提供出来了Slave API供其它内核调用。这些API实现了复杂的scatter gather 传输模式,通过这些API实现DMA传输的驱动被叫做DMA client.
DMA中调用API的顺序为:
DMA通道申请
DMA client的第一步就是要申请DMA 通道,有的DMA client 可能需要申请特殊的通道,而有的DMA client可以申请任意可用的通道。通道申请的API为dma_request_channel 或者他的某一变形API。
struct dma_chan *dma_request_channel(dma_cap_mask_t mask