<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 基于嵌入式Linux 系統(tǒng)的高速設(shè)備驅(qū)動程序?qū)崿F(xiàn)

          基于嵌入式Linux 系統(tǒng)的高速設(shè)備驅(qū)動程序?qū)崿F(xiàn)

          作者: 時間:2012-03-24 來源:網(wǎng)絡(luò) 收藏

          圖2 改進(jìn)的設(shè)備驅(qū)動流程圖

          2.2 的進(jìn)一步改進(jìn)

          基于以上幾點,為了能夠在Linux中實現(xiàn)的數(shù)據(jù)通信,對結(jié)構(gòu)作出進(jìn)一步改進(jìn)的設(shè)計。

          在設(shè)備的實現(xiàn)上,采用生產(chǎn)者-消費者模型與循環(huán)緩存相結(jié)合的結(jié)構(gòu)。將從硬件設(shè)備到核心態(tài)內(nèi)存的DMA傳輸看作生產(chǎn)者,而從核心態(tài)內(nèi)存搬移到用戶態(tài)的數(shù)據(jù)傳輸過程看作消費者;同時為DMA傳輸分配的核心態(tài)內(nèi)存采用循環(huán)鏈的結(jié)構(gòu)。

          在驅(qū)動程序中,將read()函數(shù)作為設(shè)備讀操作的主函數(shù),實現(xiàn)消費者的功能。當(dāng)read()每次被調(diào)用時,從DMA緩存鏈中讀取當(dāng)前指針?biāo)傅膬?nèi)存數(shù)據(jù),通過copy_to_user()函數(shù),將數(shù)據(jù)傳出核心態(tài),復(fù)制到用戶態(tài)內(nèi)存,以便后續(xù)的數(shù)據(jù)處理。

          而在驅(qū)動程序中,Irq_service()函數(shù)實現(xiàn)生產(chǎn)者的功能,當(dāng)有中斷產(chǎn)生后,系統(tǒng)進(jìn)入Irq_service(),表明一次DMA的傳輸結(jié)束,并且在Irq_service()中,設(shè)置下一次DMA傳輸?shù)膮?shù),包括DMA傳輸?shù)臄?shù)據(jù)大小、DMA傳輸?shù)哪繕?biāo)內(nèi)存。之后,調(diào)用interrupt_sleep_on()函數(shù),使得系統(tǒng)進(jìn)入進(jìn)程調(diào)度,等待下一次DMA的操作完成。一旦完成,就會產(chǎn)生中斷并重復(fù)以上的過程。因此,作為生產(chǎn)者的Irq_service()函數(shù),只要初始化后,就會在中斷的觸發(fā)下不斷被調(diào)用。換句話說,只要有數(shù)據(jù)到達(dá)硬件設(shè)備,就會不斷將其通過DMA的方式讀入到核心態(tài)的循環(huán)緩存中。我們可以將DMA緩存在允許的情況下,開的大一些,因為當(dāng)接收的數(shù)據(jù)呈現(xiàn)一種突發(fā)的狀態(tài)時,較小的緩沖池可能由于不能及時地將數(shù)據(jù)取走而溢出,造成數(shù)據(jù)的丟失。

          與此同時,還有個問題必須注意,即當(dāng)read()函數(shù)將緩存池中的數(shù)據(jù)都搬完之后,仍然沒有DMA的輸入。此時,read()繼續(xù)讀取的話,顯然會造成數(shù)據(jù)的錯誤,因此采用信號量是必須的。當(dāng)信號量表明,DMA的緩存已空時,若應(yīng)用程序調(diào)用read()進(jìn)行讀數(shù)據(jù)的話,將不做任何操作,并返回已讀數(shù)據(jù)量為0。當(dāng)信號量表明DMA的緩存為滿時,將DMA讀入的數(shù)據(jù)丟棄,并設(shè)置buff_full = 0。

          除此以外,我們還必須對Linux驅(qū)動進(jìn)行以下步驟的操作:設(shè)備的注冊和注銷、設(shè)備的打開和釋放。通過register_chrdev()函數(shù)向系統(tǒng)注冊設(shè)備的設(shè)備號,在設(shè)備使用結(jié)束后,可以使用unregister_chrdev()從內(nèi)核注銷設(shè)備,釋放主設(shè)備號。在設(shè)備注冊之后,由open()函數(shù)打開設(shè)備,close()釋放設(shè)備。在驅(qū)動的初始化中,需要對DMA進(jìn)行首次設(shè)置,以及緩存的分配。我們可以調(diào)用 get_free_pages()函數(shù)進(jìn)行內(nèi)存頁面的分配,它會給DMA分配內(nèi)存中連續(xù)的頁面,這對于DMA是必須的,因為DMA操作的物理地址是連續(xù)的。在內(nèi)存分配之后,我們進(jìn)行中斷的配置,通過調(diào)用函數(shù)request_irq()。接著調(diào)用request_dma() 函數(shù)對DMA進(jìn)行申請注冊。

          最后,有一點不得不引起我們的重視,即DMA一致性問題。DMA一致性的問題是指當(dāng)進(jìn)行數(shù)據(jù)DMA方式讀入時,由于沒有經(jīng)過CPU的處理,因此 CPU的CACHE會認(rèn)為該地址的內(nèi)存沒有被重寫過,而實際該內(nèi)存所存儲的數(shù)據(jù)已被改變;當(dāng)CPU需要處理該內(nèi)存的數(shù)據(jù)時,由于認(rèn)為數(shù)據(jù)沒有改變,會直接調(diào)用CACHE內(nèi)的數(shù)據(jù),造成數(shù)據(jù)錯誤,一般表現(xiàn)為數(shù)據(jù)的重復(fù)。在實際操作中,我們可以通過禁用該內(nèi)存的CACHE功能,來避免錯誤。在新版的Linux 內(nèi)核中提供dma_alloc_coherent()和dma_free_coherent()函數(shù)進(jìn)行DMA一致性內(nèi)存的分配。

          以上就是我們針對驅(qū)動改進(jìn)的程序代碼結(jié)構(gòu)。該驅(qū)動程序結(jié)構(gòu)通過將核心態(tài)的DMA操作與數(shù)據(jù)到拷貝以及用戶態(tài)上數(shù)據(jù)的處理獨立開來,依靠信號量進(jìn)行相互的制約,可以有效的避免DMA操作的頻繁性和大數(shù)據(jù)量處理的較長時間之間的矛盾。驅(qū)動程序的流程如圖2所示。

          3 應(yīng)用實例

          下面我們以視頻會議系統(tǒng)為例,介紹基于以上結(jié)構(gòu)的高速設(shè)備驅(qū)動程序的實現(xiàn)。

          在視頻會議系統(tǒng)中,AT91RM9200通過SPI接口與TI DM642 DSP芯片的McBSP接口相連進(jìn)行圖像數(shù)據(jù)的傳輸。由于數(shù)據(jù)吞吐量很大,采用一般結(jié)構(gòu)甚至是一般的DMA結(jié)構(gòu)的驅(qū)動程序都無法滿足數(shù)據(jù)的接收要求,造成數(shù)據(jù)無法實時的數(shù)據(jù)處理。我們針對該系統(tǒng)的特點,對驅(qū)動程序按照以上結(jié)構(gòu)作出改進(jìn),不但大大減輕了ARM處理器的負(fù)荷,同時能夠有效的進(jìn)行大數(shù)據(jù)量的傳輸和處理。

          表1 驅(qū)動程序改進(jìn)前后對比表

          測得碼率上限

          性能測試描述

          改進(jìn)前

          1Mbps

          當(dāng)碼率接近1Mbps時,出現(xiàn)數(shù)據(jù)丟失

          改進(jìn)后

          10Mbps

          當(dāng)碼率達(dá)到10Mbps時,驅(qū)動仍然能夠正常工作

          在我們的系統(tǒng)中,由于SPI接口需要傳輸標(biāo)清的視頻壓縮圖像,碼率一般為2Mbps,原結(jié)構(gòu)的驅(qū)動程序在碼率較高的情況下,會出現(xiàn)數(shù)據(jù)的丟失,而數(shù)據(jù)的丟失不但影響了當(dāng)前幀的圖像的質(zhì)量,而且同時會造成后面多幀圖像的質(zhì)量嚴(yán)重下降,因而無法滿足這樣高數(shù)據(jù)率傳輸?shù)男枰?。而?jīng)過改進(jìn)的驅(qū)動程序經(jīng)過測試,至少可以承受10Mbps碼率的數(shù)據(jù)傳輸,驗證證明該結(jié)構(gòu)的驅(qū)動程序可以完全勝任高速設(shè)備的數(shù)據(jù)傳輸且經(jīng)過長時間測試,性能可靠。

          4 結(jié)束語

          本文的創(chuàng)新點是提出了一種基于ARM芯片的高速數(shù)據(jù)傳輸?shù)脑O(shè)備驅(qū)動實現(xiàn)方案。首先對驅(qū)動程序程序的傳統(tǒng)結(jié)構(gòu)框架進(jìn)行了介紹。而在實際的應(yīng)用中,為了能夠適應(yīng)高速率的數(shù)據(jù)傳輸,針對ARM芯片以及Linux操作系統(tǒng)的特點,對設(shè)備驅(qū)動程序進(jìn)行了改進(jìn)。最后,以視頻會議系統(tǒng)為例,對該結(jié)構(gòu)的驅(qū)動程序進(jìn)行實現(xiàn)、測試和驗證,可完全勝任高速設(shè)備的數(shù)據(jù)傳輸且性能可靠。不僅如此,該結(jié)構(gòu)的設(shè)備驅(qū)動程序同樣適合于系統(tǒng)的各種高速設(shè)備傳輸?shù)膽?yīng)用。

          參考文獻(xiàn)

          [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] 雷鋒成 方濱 李慧杰,嵌入式網(wǎng)絡(luò)數(shù)字圖像監(jiān)控系統(tǒng),微計算機信息.2006.9-2


          上一頁 1 2 下一頁

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();