Linux驅動開發--linux下的DMA編程

來源:互聯網
上載者:User

標籤:linux驅動開發

DMA編程

DMA是一種無需要CPU的參與就可以讓外設與系統記憶體之間進行雙向資料轉送的硬體機制,使用DMA可以使系統CPU從實際的I/O資料轉送過程中擺脫出來,從而大大提高系統的吞吐率

DMA方式的資料轉送由DMA控制器控制,在傳輸期間,CPU可以並發地執行其他任務,當DMA結束後,DMA控制器通過中斷通知CPU資料轉送已經結束,然後由CPU執行相應的中斷服務程式進行後序處理.DMA可以用做記憶體與外設之間傳輸資料的方式,這種傳輸方式之下,資料並不需要經過CPU中轉。

1、  DMA與Cache一致性

假設DMA針對記憶體的目的地址與Cache緩衝的對象沒有重疊地區,DMA和Cache之間沒有問題,但是,如果DMA的目的地址與Cache所緩衝的記憶體位址訪問有重疊,經過DMA操作,Cache緩衝對應的記憶體的資料已經被修改,而CPU本身並不知道,它仍然認為Cache中的資料就是記憶體中的資料,以後訪問Cache映射的記憶體時,它仍然使用陳舊的Cache資料,這就發生了Cache與記憶體之間資料不一致性的問題。

解決由於DMA導致的Cache一致性問題的最簡單方法是直接禁止DMA目標位址範圍內記憶體的Cache功能

 

DMA只是外設與記憶體互動資料的一種方式,記憶體中用於與外設互動資料的一塊地區被稱作DMA緩衝區。

 

一般的DMA操作只能在16MB以下的記憶體中進行,因此,在使用kmalloc()和__get_free_pages()及其類似函數申請DMA緩衝區時應使用GFP_DMA標誌,這樣能保證獲得的記憶體位於DMA_ZONE,是具備DMA能力的

 

在使用DMA地區時需要注意虛擬位址、物理地址和匯流排地址

基於DMA的硬體使用匯流排地址而非物理地址,匯流排地址是從裝置角度上看到的記憶體位址,物理地址是從CPU MMU控制器外圍角度看到的記憶體位址(從CPU核角度看到的是虛擬位址)。雖然在PC上,對於ISA和PCI而言,匯流排地址即為物理地址,但並非每個平台都是如此。和DMA相關的有IOMMU,它類似於MMU,只不過IOMMU針對的是外設匯流排地址和記憶體位址之間的轉化

 

一致性DMA緩衝區

DMA映射包括兩方面工作:分配一片DMA緩衝區,為這片緩衝區產生裝置可訪問的地址。同時,DMA映射頁必須考慮Cache一致性問題,核心中提供了以下函數用於分配一個DMA一致性的記憶體地區:

Void* dma_alloc_coherent(struct device* dev,size_tsize,dma_addr_t* handle,gfp_y gfp);

此函數的返回值為申請到的DMA緩衝區的虛擬位址,此外,該函數還通過參數handle返回DMA緩衝區的匯流排地址,handle的類型為dma_addr_t,代表的是匯流排地址

Dma_alloc_coherent()申請一片DMA緩衝區,進行地址映射並保證該緩衝區的Cache一致性

Void  dma_free_coherent(struct device* dec,size_tsize,void* cpu_addr,dam_addr_t handle);

核心還提供了PCI裝置裝置申請DMA緩衝區的函數pci_alloc_consitent(),原型為:

Void* pci_alloc_consistent(struct pci_dev*pdev,size_t size,dma_addr_t* dam_addrp);

 

流式DMA緩衝區

並非所有的DMA緩衝區都是驅動申請的,如果驅動申請的,用一致性DMA緩衝區自然最方便,直接考慮了Cache一致性問題,但是,緩衝區來自核心的較上層,上層很可能用的是普通的kmalloc() _get_free_pages()等方法,這時候就要使用流式DMA映射。流式DMA緩衝區使用的一般步驟如下:

         進行流式DMA映射

         執行DMA操作

         進行流式DMA去映射

核心提供了和DMA相關的函數

在某些體繫結構中,流式映射也能夠擁有多個不連續的頁和多個“分散/聚集”緩衝區。建立流式映射時,必須告訴核心資料流動的方向。

DMA_TO_DEVICE

DEVICE_TO_DMA

如果資料被發送到裝置,使用DMA_TO_DEVICE;而如果資料被發送到CPU,則使用DEVICE_TO_DMA。

DMA_BIDIRECTTONAL

如果資料可雙向移動,則使用該值

DMA_NONE

該符號只是出於調試目的。

當只有一個緩衝區要被傳輸的時候,使用下函數映射它:

dma_addr_t dma_map_single(struct device *dev, void *buffer, size_tsize, enum dma_data_direction direction);

返回值是匯流排地址,可以把它傳遞給裝置;如果執行錯誤,返回NULL。

當傳輸完畢後,使用下函數刪除映射:

void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,size_t size, enum dma-data_direction direction);

使用流式DMA的原則:

一是緩衝區只能用於這樣的傳送,即其傳送方向匹配與映射時給定的方向值;

二是一旦緩衝區被映射,它將屬於裝置,不是處理器。直到緩衝區被撤銷映射前,驅動程式不能以任何方式訪問其中的內容。只用當dma_unmap_single函數被調用後,顯示重新整理處理器緩衝中的資料,驅動程式才能安全訪問其中的內容。

三是在DMA出於活動期間內,不能撤銷對緩衝區的映射,否則會嚴重破壞系統的穩定性。             

如果要映射的緩衝區位於裝置不能訪問的記憶體區段(高端記憶體),怎麼辦?一些體繫結構只產生一個錯誤,但是其他一些系統結構件建立一個回彈緩衝區。回彈緩衝區就是記憶體中的獨立地區,它可被裝置訪問。如果使用DMA_TO_DEVICE標誌映射緩衝區,並且需要使用回彈緩衝區,則在最初緩衝區中的內容作為映射操作的一部分被拷貝。很明顯,在拷貝後,最初緩衝區內容的改變對裝置不可見。同樣DEVICE_TO_DMA回彈緩衝區被 dma_unmap_single函數拷貝回最初的緩衝區中,也就是說,直到拷貝操作完成,來自裝置的資料才可用。

有時候,驅動程式需要不經過撤銷映射就訪問流式DMA緩衝區的內容,為此核心提供了如下調用:

void dma_sync_single_for_cpu(struct device *dev, dma_handle_tbus_addr, size_t size, enum dma_data_directction direction);

應該在處理器訪問流式DMA緩衝區前調用該函數。一旦調用了該函數,處理器將“擁有”DMA緩衝區,並可根據需要對它進行訪問。然後在裝置訪問緩衝區前,應該調用下面的函數將所有權交還給裝置:

void dma_sync_single_for_device(struct device *dev, dma_handle_tbus_addr, size_t size, enum dma_data_direction direction);

再次強調,處理器在調用該函數後,不能再訪問DMA緩衝區了。

 

 

申請和釋放DMA通道

和中斷一樣,在使用DMA之前,裝置驅動程式需首先向系統申請DMA通道,申請DMA通道函數:

Int request_dma(unsigned int dmanr,const char*device_id);

裝置結構體指標可作為傳入device_id的最佳參數

使用完DMA通道後,需要釋放

Void free_dma(unsigned int dmanr);

Linux裝置驅動中DMA相關代碼流程:

1、request_dma()並初始化DMAC    申請DMA緩衝區 (在裝置驅動模組載入或open()函數中進行)

2、進行DMA傳輸  (在write() read() ioctl()等功能函數中進行)

3、若使能了對應中斷,進行DMA傳輸後的中斷處理 (在中斷處理常式中進行)

4、釋放DMA緩衝區 free_dma() (在裝置驅動模組卸載或relese()函數中進行 )

 

Linux驅動開發--linux下的DMA編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.