基于嵌入式Linux 系統的高速設備驅動程序實現
圖2 改進的設備驅動流程圖
2.2 驅動程序的進一步改進
基于以上幾點,為了能夠在Linux中實現高速設備的數據通信,對驅動程序結構作出進一步改進的設計。
在設備驅動程序的實現上,采用生產者-消費者模型與循環緩存相結合的結構。將從硬件設備到核心態內存的DMA傳輸看作生產者,而從核心態內存搬移到用戶態的數據傳輸過程看作消費者;同時為DMA傳輸分配的核心態內存采用循環鏈的結構。
在驅動程序中,將read()函數作為設備讀操作的主函數,實現消費者的功能。當read()每次被調用時,從DMA緩存鏈中讀取當前指針所指的內存數據,通過copy_to_user()函數,將數據傳出核心態,復制到用戶態內存,以便后續的數據處理。
而在驅動程序中,Irq_service()函數實現生產者的功能,當有中斷產生后,系統進入Irq_service(),表明一次DMA的傳輸結束,并且在Irq_service()中,設置下一次DMA傳輸的參數,包括DMA傳輸的數據大小、DMA傳輸的目標內存。之后,調用interrupt_sleep_on()函數,使得系統進入進程調度,等待下一次DMA的操作完成。一旦完成,就會產生中斷并重復以上的過程。因此,作為生產者的Irq_service()函數,只要初始化后,就會在中斷的觸發下不斷被調用。換句話說,只要有數據到達硬件設備,就會不斷將其通過DMA的方式讀入到核心態的循環緩存中。我們可以將DMA緩存在允許的情況下,開的大一些,因為當接收的數據呈現一種突發的狀態時,較小的緩沖池可能由于不能及時地將數據取走而溢出,造成數據的丟失。
與此同時,還有個問題必須注意,即當read()函數將緩存池中的數據都搬完之后,仍然沒有DMA的輸入。此時,read()繼續讀取的話,顯然會造成數據的錯誤,因此采用信號量是必須的。當信號量表明,DMA的緩存已空時,若應用程序調用read()進行讀數據的話,將不做任何操作,并返回已讀數據量為0。當信號量表明DMA的緩存為滿時,將DMA讀入的數據丟棄,并設置buff_full = 0。
除此以外,我們還必須對Linux驅動進行以下步驟的操作:設備的注冊和注銷、設備的打開和釋放。通過register_chrdev()函數向系統注冊設備的設備號,在設備使用結束后,可以使用unregister_chrdev()從內核注銷設備,釋放主設備號。在設備注冊之后,由open()函數打開設備,close()釋放設備。在驅動的初始化中,需要對DMA進行首次設置,以及緩存的分配。我們可以調用 get_free_pages()函數進行內存頁面的分配,它會給DMA分配內存中連續的頁面,這對于DMA是必須的,因為DMA操作的物理地址是連續的。在內存分配之后,我們進行中斷的配置,通過調用函數request_irq()。接著調用request_dma() 函數對DMA進行申請注冊。
最后,有一點不得不引起我們的重視,即DMA一致性問題。DMA一致性的問題是指當進行數據DMA方式讀入時,由于沒有經過CPU的處理,因此 CPU的CACHE會認為該地址的內存沒有被重寫過,而實際該內存所存儲的數據已被改變;當CPU需要處理該內存的數據時,由于認為數據沒有改變,會直接調用CACHE內的數據,造成數據錯誤,一般表現為數據的重復。在實際操作中,我們可以通過禁用該內存的CACHE功能,來避免錯誤。在新版的Linux 內核中提供dma_alloc_coherent()和dma_free_coherent()函數進行DMA一致性內存的分配。
以上就是我們針對高速設備驅動改進的程序代碼結構。該驅動程序結構通過將核心態的DMA操作與數據到拷貝以及用戶態上數據的處理獨立開來,依靠信號量進行相互的制約,可以有效的避免高速設備DMA操作的頻繁性和大數據量處理的較長時間之間的矛盾。驅動程序的流程如圖2所示。
3 應用實例
下面我們以視頻會議系統為例,介紹基于以上結構的高速設備驅動程序的實現。
在視頻會議系統中,AT91RM9200通過SPI接口與TI DM642 DSP芯片的McBSP接口相連進行圖像數據的傳輸。由于數據吞吐量很大,采用一般結構甚至是一般的DMA結構的驅動程序都無法滿足數據的接收要求,造成數據無法實時的數據處理。我們針對該系統的特點,對驅動程序按照以上結構作出改進,不但大大減輕了ARM處理器的負荷,同時能夠有效的進行大數據量的傳輸和處理。
表1 驅動程序改進前后對比表
測得碼率上限 | 性能測試描述 | |
改進前 | 1Mbps | 當碼率接近1Mbps時,出現數據丟失 |
改進后 | 10Mbps | 當碼率達到10Mbps時,驅動仍然能夠正常工作 |
在我們的系統中,由于SPI接口需要傳輸標清的視頻壓縮圖像,碼率一般為2Mbps,原結構的驅動程序在碼率較高的情況下,會出現數據的丟失,而數據的丟失不但影響了當前幀的圖像的質量,而且同時會造成后面多幀圖像的質量嚴重下降,因而無法滿足這樣高數據率傳輸的需要。而經過改進的驅動程序經過測試,至少可以承受10Mbps碼率的數據傳輸,驗證證明該結構的驅動程序可以完全勝任高速設備的數據傳輸且經過長時間測試,性能可靠。
4 結束語
本文的創新點是提出了一種基于ARM芯片的高速數據傳輸的設備驅動實現方案。首先對嵌入式Linux驅動程序程序的傳統結構框架進行了介紹。而在實際的應用中,為了能夠適應高速率的數據傳輸,針對ARM芯片以及Linux操作系統的特點,對設備驅動程序進行了改進。最后,以視頻會議系統為例,對該結構的驅動程序進行實現、測試和驗證,可完全勝任高速設備的數據傳輸且性能可靠。不僅如此,該結構的設備驅動程序同樣適合于嵌入式Linux系統的各種高速設備傳輸的應用。
參考文獻
[1] Alessandro Rubini Linux Device Drivers 0'Reilly Assocoates,Inc. 1998.
[2] Karim Yagbmour Building Embedded Linux System 0'Reilly Media,Inc. 2004.
[3] Linux kernel, version 2.4.30
[4] 雷鋒成 方濱 李慧杰,嵌入式網絡數字圖像監控系統,微計算機信息.2006.9-2
評論