linux总线驱动之DMA传输


DMA的工作流程

不会奔跑的高铁

 

 

对于linux中的DMA,其实是在写数据寄存器的时候就可以用dma的传输来代替。就像spi设备,在发送和接收数据的时候都是要往数据寄存器中写数据的。比如那个寄存器是SPI_DATA,如果用cpu来传输的话就是writel(data, SPI_DATA);而用dma传输就是配置好要传输的buf长度,然后源地址就是buf的地址,目标地址就是SPI_DATA。

       这里还要注意经过cpu的是虚拟地址,而dma传输的是物理地址。

       其实dma传输就是dma控制在两个物理地址之间传输数据。

 

Linux下用dma传输主要调用下面这些函数就可以实现外部的dma,下图为流程图

 

1、初始化DMA

 1 dma_cap_zero(mask);
 2 dma_cap_set(DMA_SLAVE,mask);
 3  
 4 /*1. Init rx channel */
 5 dws->rxchan= dma_request_channel(mask, dma_chan_filter, params);// 主要就是申请DMA通道。dma_chan_filter这个函数主要是查找你的dma传输的设备的请求信号线,其具体是在注册时填写的。  这里会根据这个函数返回的真假来判断已经注册在总线上的dma slave的。
 6 buf =kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL); //申请一块地址,用来DMA传输的数据就放在这里 

7 sg_init_one(&dma_dev->dmatx.sg, buf, DMA_BUFFER_SIZE); //初始化,其主要为了发送时虚拟地址和物理地址的映射。

 

2、启动DMA

 1 struct dma_async_tx_descriptor *txdesc = NULL;
 2 struct dma_chan *txchan,;
 3 struct dma_slave_config txconf;
 4  
 5 txchan= dws->txchan;
 6       
 7  /*2. Prepare the TX dma transfer */
 8 txconf.direction= DMA_TO_DEVICE;              //表示dma传输方向为发送
 9 txconf.dst_addr= dws->dma_addr;                   //目标地址,物理地址
10 txconf.dst_maxburst= LNW_DMA_MSIZE_16; //最大传输的字节数
11 txconf.dst_addr_width= DMA_SLAVE_BUSWIDTH_2_BYTES;  //数据的位宽
12  
13 txchan->device->device_control(txchan,DMA_SLAVE_CONFIG,
14                                    (unsigned long) &txconf);
15       
16 dws->tx_sgl.length= dws->len;    //要传输的数据的长度
17  
18 dma_map_sg(dma_dev->dev,&dmatx->sg, 1, DMA_TO_DEVICE);
19 //通过这个函数来实现虚拟地址和物理地址的映射。
20  
21  txdesc= txchan->device->device_prep_slave_sg(txchan,
22                             &dws->tx_sgl,
23                             1,
24                             DMA_TO_DEVICE,
25                             DMA_PREP_INTERRUPT| DMA_COMPL_SKIP_DEST_UNMAP);
26  txdesc->callback= dw_spi_dma_done;   //传输完成后的回调函数
27  txdesc->callback_param= params;      //回调函数中的参数
28  
29  dmaengine_submit(txdesc);
30 dma_dev->device_issue_pending(txchan); // 启动dma传输了

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM