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