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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于微處理器和UDAl34l的嵌入式音頻系統(tǒng)設(shè)計(jì)

          基于微處理器和UDAl34l的嵌入式音頻系統(tǒng)設(shè)計(jì)

          作者: 時(shí)間:2011-08-22 來源:網(wǎng)絡(luò) 收藏
          4 Linux下驅(qū)動(dòng)的實(shí)現(xiàn)

          本文引用地址:http://www.ex-cimer.com/article/150313.htm

            設(shè)備驅(qū)動(dòng)程序是操作內(nèi)核和機(jī)器硬件之間的接口,為應(yīng)用程序屏蔽了硬件細(xì)節(jié)。設(shè)備驅(qū)動(dòng)是內(nèi)核的一部分,主要完成以下功能:設(shè)備初始化和釋放;設(shè)備管理,包括實(shí)時(shí)參數(shù)設(shè)置及提供對(duì)設(shè)備的操作接口;讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)并回送應(yīng)用程序請(qǐng)求的數(shù)據(jù);檢測(cè)和處理設(shè)備出現(xiàn)的錯(cuò)誤。

            設(shè)備驅(qū)動(dòng)程序主要通過對(duì)硬件的控制實(shí)現(xiàn)流的傳輸,同時(shí)向上層提供標(biāo)準(zhǔn)的音頻接口。筆者的音頻接口驅(qū)動(dòng)向上提供2個(gè)標(biāo)準(zhǔn)接口:數(shù)字音頻處理(Digital Sound Processing-DSP),負(fù)責(zé)音頻數(shù)據(jù)的傳輸即播放數(shù)字化聲音文件和錄音操作等;混音器(MIXER),負(fù)責(zé)對(duì)輸出音頻進(jìn)行混音處理,如音量調(diào)節(jié)、高低音控制等。這2個(gè)標(biāo)準(zhǔn)接口分別對(duì)應(yīng)設(shè)備文件dev/dsp和dev/mixer。

            整個(gè)音頻驅(qū)動(dòng)的實(shí)現(xiàn)分為初始化、打開設(shè)備、DSP驅(qū)動(dòng)、MIXER驅(qū)動(dòng)和釋放設(shè)備等部分。

            4.1 初始化、打開設(shè)備

            設(shè)備初始化主要完成對(duì)音量、采樣頻率、L3接口等的初始化,并且注冊(cè)設(shè)備。通過函數(shù)audio_init(void)完成以下具體功能:

            · S3C2410控制端口(GPBl-GPB3)的初始化;

            · 為設(shè)備分配DMA通道;

            · 的初始化;

            · 注冊(cè)audio設(shè)備和mixer設(shè)備。

            · 打開設(shè)備由打開函數(shù)open()完成以下功能;

            · 設(shè)置好ⅡS和L3總線;

            · 準(zhǔn)備好聲道、采樣寬度等參數(shù)并通知設(shè)備;

            · 根據(jù)采樣參數(shù)計(jì)算出緩沖區(qū)大小;

            · 分配相應(yīng)大小的DMA緩沖區(qū)供設(shè)備使用。

            4.2 DSP驅(qū)動(dòng)的實(shí)現(xiàn)

            DSP驅(qū)動(dòng)實(shí)現(xiàn)了音頻數(shù)據(jù)的傳輸即播放和錄音的數(shù)據(jù)傳輸。同時(shí)提供ioctl對(duì)UDA134l中的DAC和ADC采樣率進(jìn)行控制。采樣率的控制主要是讀寫內(nèi)的采樣率控制寄存器,所以驅(qū)動(dòng)的主要部分就是控制音頻數(shù)據(jù)的傳輸。

            驅(qū)動(dòng)中通過結(jié)構(gòu)static audio_state來描述整個(gè)音頻的狀態(tài),其中最主要的是2個(gè)數(shù)據(jù)流結(jié)構(gòu)audio_in和audio_out。這2個(gè)數(shù)據(jù)流結(jié)構(gòu)分別描述輸入音頻流和輸出音頻流的信息。通過對(duì)audio_in和audio_out的操作分別實(shí)現(xiàn)音頻的輸入和輸出(音頻的播放和錄音),本驅(qū)動(dòng)的主要內(nèi)容是數(shù)據(jù)流結(jié)構(gòu)的和實(shí)現(xiàn)。該結(jié)構(gòu)應(yīng)該包含音頻緩沖區(qū)的信息、DMA的相關(guān)信息、所用到的信號(hào)量及FIFO的入口寄存器的地址。

            為了提高的吞吐量,系統(tǒng)使用DMA技術(shù)直接將需要回放或錄制的聲音存放在內(nèi)核的DMA緩存區(qū)中,由于S3C2410的DMA控制器沒有內(nèi)置的DMA存儲(chǔ)區(qū)域,因而驅(qū)動(dòng)程序必須在內(nèi)存內(nèi)為音頻設(shè)備分配DMA緩存區(qū)。緩沖區(qū)設(shè)置是否合理非常關(guān)鍵。以write()函數(shù)為例,因?yàn)橐纛l數(shù)據(jù)量通常較大,而緩存太小容易造成緩存溢出,所以要采用較大的緩沖區(qū)。而要填充大的緩沖區(qū),CPU就要一次處理大量的數(shù)據(jù),這樣處理數(shù)據(jù)時(shí)間較長(zhǎng),容易造成延遲。筆者采用多個(gè)緩存的機(jī)制,將緩沖區(qū)分為多個(gè)數(shù)據(jù)段。數(shù)據(jù)段的個(gè)數(shù)和大小分別在數(shù)據(jù)流結(jié)構(gòu)中指定。這樣把大的數(shù)據(jù)段分為幾個(gè)小段處理,每處理一小段數(shù)據(jù)就可以通過DMA發(fā)送出去。read函數(shù)也是如此,DMA每發(fā)來一小段數(shù)據(jù)就可以處理,不用等到大緩沖區(qū)都填滿才處理數(shù)據(jù)。這里還提供了ioctl接口給上層調(diào)用,這樣上層可以根據(jù)音頻數(shù)據(jù)的精度即數(shù)據(jù)流量來調(diào)整緩沖區(qū)數(shù)據(jù)段的大小和個(gè)數(shù),以取得最好的傳輸效果。

            4.3 MIXER驅(qū)動(dòng)的實(shí)現(xiàn)

            MIXER驅(qū)動(dòng)只控制混音效果,并不執(zhí)行讀寫操作,所以MIXER的文件操作結(jié)構(gòu)只實(shí)現(xiàn)了1個(gè)ioctl調(diào)用,提供給上層設(shè)置CODEC的混音效果。驅(qū)動(dòng)中主要實(shí)現(xiàn)了1個(gè)結(jié)構(gòu)體struct UDAl34l_codec。該結(jié)構(gòu)體描述了CODEC的基本信息,主要是實(shí)現(xiàn)了CODEC寄存器的讀寫函數(shù)和混音的控制函數(shù)。MIXER文件操作結(jié)構(gòu)中的ioctl就是調(diào)用U-DAl341_codec中的混音控制函數(shù)來實(shí)現(xiàn)的。

            4.4 設(shè)備的卸載

            設(shè)備的卸載由注銷函數(shù)close()來完成。注銷函數(shù)使用注冊(cè)時(shí)得到的設(shè)備號(hào),同時(shí)釋放驅(qū)動(dòng)程序使用的各種系統(tǒng)資源,如DMA和緩沖區(qū)等。

            5 結(jié)束語

            該系統(tǒng)已經(jīng)在S3C2410的開發(fā)平臺(tái)上得到了實(shí)現(xiàn),可以順利進(jìn)行音頻的播放和采集,并取得良好的效果。

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

          上一頁 1 2 下一頁

          評(píng)論


          相關(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); })();