LinuxALSA聲卡驅(qū)動(dòng)開(kāi)發(fā)實(shí)踐PPT課件_第1頁(yè)
LinuxALSA聲卡驅(qū)動(dòng)開(kāi)發(fā)實(shí)踐PPT課件_第2頁(yè)
LinuxALSA聲卡驅(qū)動(dòng)開(kāi)發(fā)實(shí)踐PPT課件_第3頁(yè)
LinuxALSA聲卡驅(qū)動(dòng)開(kāi)發(fā)實(shí)踐PPT課件_第4頁(yè)
LinuxALSA聲卡驅(qū)動(dòng)開(kāi)發(fā)實(shí)踐PPT課件_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

.,1,LinuxALSA聲卡驅(qū)動(dòng)開(kāi)發(fā)最佳實(shí)踐,本實(shí)踐是在Linux基礎(chǔ)培訓(xùn)(2)-驅(qū)動(dòng)開(kāi)發(fā)最佳實(shí)踐基礎(chǔ)上進(jìn)行的,.,2,目錄,一、ALSA架構(gòu)簡(jiǎn)介二、最佳實(shí)踐的目標(biāo)、目的、方法三、具體步驟四、總結(jié),.,3,目錄,一、ALSA架構(gòu)簡(jiǎn)介二、最佳實(shí)踐的目標(biāo)、目的、方法三、具體步驟四、總結(jié),.,4,一、ALSA架構(gòu)簡(jiǎn)介,ALSA架構(gòu)特點(diǎn),支持多種聲卡設(shè)備模塊化的內(nèi)核驅(qū)動(dòng)程序支持SMP和多線程提供應(yīng)用程序開(kāi)發(fā)庫(kù)兼容OSS應(yīng)用程序開(kāi)發(fā),.,5,一、ALSA架構(gòu)簡(jiǎn)介,ALSA是AdvancedLinuxSoundArchitecture,高級(jí)Linux聲音架構(gòu)的簡(jiǎn)稱,它在Linux操作系統(tǒng)上提供了音頻和MIDI(MusicalInstrumentDigitalInterface,音樂(lè)設(shè)備數(shù)字化接口)的支持。它包含API庫(kù)和工具、內(nèi)核驅(qū)動(dòng)集合,對(duì)Linux聲音進(jìn)行支持。ALSA包含一系列內(nèi)核驅(qū)動(dòng)對(duì)不同的聲卡進(jìn)行支持,還提供了libasound的API庫(kù)。用這些進(jìn)行寫程序不需要打開(kāi)設(shè)備等操作,所以編程人員在寫程序的時(shí)候不會(huì)被底層的東西困擾。ALSA自帶的應(yīng)用程序是alsa-utils工具包,包括aplay、alsamixer等。aplay用于在ASLA上播放音頻。alsamixer用于改變音頻信號(hào)的音量。alsa-lib是用戶空間的函數(shù)庫(kù),提供了libasound.so給應(yīng)用程序使用,應(yīng)用程序應(yīng)包含頭文件asoundlib.h。這個(gè)庫(kù)通過(guò)提供封裝函數(shù)(ALSA-API),使ALSA應(yīng)用程序編寫起來(lái)更容易。alsa-lib中有control,timer,dmix,pcm等,都是以插件(plugin)的形式存在的。alsa-lib通過(guò)硬件訪問(wèn)層的系統(tǒng)調(diào)用與內(nèi)核層進(jìn)行交互。alsa-driver是音頻設(shè)備的alsa內(nèi)核部分的驅(qū)動(dòng)。集成在內(nèi)核里面,大多是以模塊的方式存在。可分為三層。(1)最底層是硬件操控層,負(fù)責(zé)實(shí)現(xiàn)硬件操縱訪問(wèn)的功能,這也是聲卡驅(qū)動(dòng)程序中用戶需實(shí)現(xiàn)的主要部分;(2)中間層是ASLA驅(qū)動(dòng)的核心部分,它由各種功能的音頻設(shè)備組件構(gòu)成,為用戶提供了一些預(yù)定義組件(如PCM、AC97、音序器和控制器等),另外用戶也可以自行定義設(shè)備組件;(3)驅(qū)動(dòng)的最上層是聲卡對(duì)象描述層,它是聲卡硬件的抽象描述,內(nèi)核通過(guò)這些描述可以得知該聲卡硬件的功能、設(shè)備組件和操作方法等。,.,6,一、ALSA架構(gòu)簡(jiǎn)介,這是另一個(gè)ASLA架構(gòu)圖。與上一個(gè)圖大同小異。從內(nèi)核driver層、lib層到應(yīng)用層勾畫出了彼此之間的關(guān)系。圖中左下角OSS相關(guān)部分是為了兼容OSS驅(qū)動(dòng)模型而存在的。不是本實(shí)踐的相關(guān)部分。,.,7,一、ALSA架構(gòu)簡(jiǎn)介,左圖是從代碼的角度體現(xiàn)了alsa-lib和alsa-driver及hardware的交互關(guān)系。用戶層的alsa-lib通過(guò)操作alsa-driver創(chuàng)建的設(shè)備文件/dev/snd/pcmC0D0p等對(duì)內(nèi)核層進(jìn)行訪問(wèn)。內(nèi)核層的alsa-drivier驅(qū)動(dòng)再經(jīng)由soundcore對(duì)硬件聲卡芯片進(jìn)行訪問(wèn)。從而實(shí)現(xiàn)了appalsa-libalsa-driverhardware的操作。圖中右上角OSS相關(guān)部分是為了兼容OSS驅(qū)動(dòng)模型而存在的。不是本實(shí)踐的相關(guān)部分。,.,8,目錄,一、ALSA架構(gòu)簡(jiǎn)介二、最佳實(shí)踐的目標(biāo)、目的、方法三、具體步驟四、總結(jié),.,9,二、最佳實(shí)踐的目標(biāo)、目的、方法,在alsa的整體架構(gòu)中,alsa-driver的硬件操控層,負(fù)責(zé)實(shí)現(xiàn)硬件操縱訪問(wèn),這也是聲卡驅(qū)動(dòng)程序中用戶需實(shí)現(xiàn)的主要部分。我們要實(shí)現(xiàn)的是針對(duì)特定聲卡芯片ens1371的控制在這里把它叫做device-driver(設(shè)備驅(qū)動(dòng)),alsa-driver的其它部分叫做alsa-driver(alsa驅(qū)動(dòng))。,.,10,目錄,一、ALSA架構(gòu)簡(jiǎn)介二、最佳實(shí)踐的目標(biāo)、目的、方法三、具體步驟四、總結(jié),.,11,三、具體步驟,1.準(zhǔn)備工作。(1)使用alsa自帶的aplay工具或其它應(yīng)用程序播放音頻,測(cè)試開(kāi)發(fā)環(huán)境是否能夠正常播放音頻。如果不能播放,可以用alsamixer等工具查看音量是否被靜音了。總之,如果正常環(huán)境如果都不能播放音頻,那我們后續(xù)的工作也就不能檢驗(yàn)正確與否了。aplay工具shell中命令如下:#apt-getinstallalsa-utils/初次使用安裝alsa-utils工具,以后直接執(zhí)行下一步就可以了。#aplay/opt/test_files/pcm.wav/aplay后面的文件路徑根據(jù)自己的實(shí)際情況填寫。紅色文字表示shell中輸入的命令。alsamixer工具shell中命令如下:#apt-getinstallalsa-utils/初次使用安裝alsa-utils工具,以后直接執(zhí)行下一步就可以了。#alsamixer。alsamixer中,、方向鍵可以調(diào)整焦點(diǎn),、方向鍵可以調(diào)整音量,esc鍵退出。也可以用數(shù)字或+、-鍵調(diào)整音量。(2)檢查使用的PC的聲卡是否是ENS1371,shell中命令如下:#lspci|grep“1371”ENS1371聲卡會(huì)顯示類似如下字樣#02:02.0Multimediaaudiocontroller:EnsoniqES1371AudioPCI-97(rev02)如果不是ENS1371,下文可作為參考根據(jù)自己的實(shí)際情況進(jìn)行。,.,12,三、具體步驟,1.準(zhǔn)備工作。(2)新建工作目錄如alsa-ens1371-dev-driver,在工作目錄中新建文件ens1371-playback.c。(3)制作makefile。新建文件Makefile。參照Linux基礎(chǔ)培訓(xùn)(2)-驅(qū)動(dòng)開(kāi)發(fā)最佳實(shí)踐-1.pptx第5頁(yè)編寫Makefile。Makefile內(nèi)容如下:2.查看內(nèi)核linux-source-2.6.26/sound/pci/ens1371.c的代碼,內(nèi)容如下:即在定義宏CHIP1371的基礎(chǔ)上,使用ens1370.c。,ifneq($(KERNELRELEASE),)obj-m:=ens1371-playback.oelseKBUILD:=/lib/modules/uname-r/buildmodules:make-C$(KBUILD)M=$(shellpwd)modulesclean:rm-f*.o*core.depend.*.cmd*.ko*.mod.c*.order*.symversrm-rf.tmp_versionsendif,#defineCHIP1371#includeens1370.c“,.,13,三、具體步驟,3.抽取ens1370.c(位于linux-source-2.6.26/sound/pci)中Linux通用驅(qū)動(dòng)程序核心,添加到ens1371-playback.c中并make,測(cè)試??梢韵忍砑涌蚣?,再向框架中逐步添加函數(shù)??梢源蛴∵m當(dāng)?shù)膌og信息,不會(huì)影響ens1371的流程。Linux通用驅(qū)動(dòng)程序代碼如下:4.根據(jù)ens1370.c的代碼,向init和exit中添加實(shí)現(xiàn)函數(shù)。根據(jù)調(diào)用關(guān)系實(shí)現(xiàn)一個(gè)被調(diào)用函數(shù)的最小化定義(如下頁(yè)圖中的snd_audiopci_probe()和snd_audiopci_remove()),以填充調(diào)用函數(shù),并將無(wú)關(guān)部分注釋掉,減輕代碼量。注意注釋無(wú)關(guān)部分時(shí)需要注意,有些不能確定有沒(méi)有用,可以先留著,另外,除了函數(shù)外,其他部分的最好用注釋,不要直接刪除,以便在后面檢查是否刪除了有用的部分。定義最小化的函數(shù)后,代碼是可以編譯,并可以加載到內(nèi)核的,再逐步添寫被調(diào)用函數(shù),以此類推,直到所有的調(diào)用關(guān)系全部被添加進(jìn)代碼。如向init和exit中添加實(shí)現(xiàn)函數(shù):,#defineCHIP1371#include#defineENS1371_DEBUG#ifdefENS1371_DEBUG#defineFUNC_LOG()printk(KERN_ERR“FUNC_LOG:%d%s()n,_LINE_,_FUNCTION_)#endifstaticint_initalsa_card_ens137x_init(void)FUNC_LOG();staticvoid_exitalsa_card_ens137x_exit(void)FUNC_LOG();module_init(alsa_card_ens137x_init)module_exit(alsa_card_ens137x_exit),.,14,#defineCHIP1371#include#include#defineENS1371_DEBUG#ifdefENS1371_DEBUG#defineFUNC_LOG()printk(KERN_ERRFUNC_LOG:%d:%s()n,_LINE_,_FUNCTION_)#endif#defineDRIVER_NAMEENS1371“staticstructpci_device_idsnd_audiopci_ids=/#ifdefCHIP1370/0 x1274,0 x5000,PCI_ANY_ID,PCI_ANY_ID,0,0,0,/*ES1370*/#endif#ifdefCHIP13710 x1274,0 x1371,PCI_ANY_ID,PCI_ANY_ID,0,0,0,/*ES1371*/0 x1274,0 x5880,PCI_ANY_ID,PCI_ANY_ID,0,0,0,/*ES1373-CT5880*/0 x1102,0 x8938,PCI_ANY_ID,PCI_ANY_ID,0,0,0,/*EctivaEV1938*/#endif0,;staticint_devinitsnd_audiopci_probe(structpci_dev*pci,conststructpci_device_id*pci_id)FUNC_LOG();return0;staticvoid_devexitsnd_audiopci_remove(structpci_dev*pci)FUNC_LOG();staticstructpci_driverdriver=.name=DRIVER_NAME,.id_table=snd_audiopci_ids,.probe=snd_audiopci_probe,.remove=_devexit_p(snd_audiopci_remove),#ifdefCONFIG_PM/.suspend=snd_ensoniq_suspend,/.resume=snd_ensoniq_resume,#endif;staticint_initalsa_card_ens137x_init(void)FUNC_LOG();returnpci_register_driver(module_init(alsa_card_ens137x_init)module_exit(alsa_card_ens137x_exit),三、具體步驟,.,15,三、具體步驟,5.make、insmod、rmmod驅(qū)動(dòng)模塊示例:,注意insmodens1371-playback.ko前,要先卸載系統(tǒng)中原有的ens1371模塊snd_ens1371。否則,在定義了DRIVER_NAME后,insmod時(shí)就會(huì)出錯(cuò)。圖中,紅色是shell中輸入的命令,黃色是系統(tǒng)打印的信息,而綠色是我們的模塊打印的log。另外,驅(qū)動(dòng)模塊的單步調(diào)試可以參照Linux基礎(chǔ)培訓(xùn)(2)-驅(qū)動(dòng)開(kāi)發(fā)最佳實(shí)踐-1.pptx。,.,16,三、具體步驟,6.仿照snd_audiopci_probe()和snd_audiopci_remove()的填充與alsa_card_ens137x_init()和alsa_card_ens137x_exit()類似,如此一級(jí)一級(jí)的填充下去,直至模塊可以播放出聲音。對(duì)于snd_audiopci_probe()這樣比較復(fù)雜的函數(shù),要一行一行的添加,邊添加邊調(diào)試。如遇到變量等應(yīng)該在前面函數(shù)中賦值而還沒(méi)有實(shí)現(xiàn)的部分,可以先用if宏等方法暫時(shí)注釋掉,如下頁(yè)代碼中的紅色部分。添加的代碼如下:,#defineCHIP1371#include#include#include#include#defineENS1371_DEBUG#ifdefENS1371_DEBUG#defineFUNC_LOG()printk(KERN_ERRFUNC_LOG:%d:%s()n,_LINE_,_FUNCTION_)#endif#defineDRIVER_NAMEENS1371“staticstructpci_device_idsnd_audiopci_ids=;staticintindexSNDRV_CARDS=SNDRV_DEFAULT_IDX;/*Index0-MAX*/staticchar*idSNDRV_CARDS=SNDRV_DEFAULT_STR;/*IDforthiscard*/staticintenableSNDRV_CARDS=SNDRV_DEFAULT_ENABLE_PNP;/*Enableswitches*/staticintspdifSNDRV_CARDS;staticintlineioSNDRV_CARDS;structensoniq;MODULE_DEVICE_TABLE(pci,snd_audiopci_ids);staticint_devinitsnd_ensoniq_1371_mixer(structensoniq*ensoniq,inthas_spdif,inthas_line)FUNC_LOG();return(0);staticint_devinitsnd_ensoniq_pcm(structensoniq*ensoniq,intdevice,structsnd_pcm*rpcm)FUNC_LOG();return0;staticint_devinitsnd_ensoniq_create(structsnd_card*card,structpci_dev*pci,structensoniq*rensoniq)FUNC_LOG();return0;,.,17,三、具體步驟,6.代碼續(xù):,staticint_devinitsnd_audiopci_probe(structpci_dev*pci,conststructpci_device_id*pci_id)staticintdev;structsnd_card*card;structensoniq*ensoniq;interr,pcm_devs2;FUNC_LOG();if(dev=SNDRV_CARDS)return-ENODEV;if(!enabledev)dev+;return-ENOENT;card=snd_card_new(indexdev,iddev,THIS_MODULE,0);if(card=NULL)return-ENOMEM;if(err=snd_ensoniq_create(card,pci,strcpy(card-driver,DRIVER_NAME);strcpy(card-shortname,EnsoniqAudioPCI);#ifdefENS1371_RESERVEDsprintf(card-longname,%s%sat0 x%lx,irq%i,card-shortname,card-driver,ensoniq-port,ensoniq-irq);#endifif(err=snd_card_register(card)0)snd_card_free(card);returnerr;pci_set_drvdata(pci,card);dev+;return0;staticvoid_devexitsnd_audiopci_remove(structpci_dev*pci)FUNC_LOG();snd_card_free(pci_get_drvdata(pci);pci_set_drvdata(pci,NULL);staticstructpci_driverdriver=.name=DRIVER_NAME,.id_table=snd_audiopci_ids,.probe=snd_audiopci_probe,.remove=_devexit_p(snd_audiopci_remove),#ifdefCONFIG_PM/.suspend=snd_ensoniq_suspend,/.resume=snd_ensoniq_resume,#endif;staticint_initalsa_card_ens137x_init(void)FUNC_LOG();returnpci_register_driver(module_init(alsa_card_ens137x_init)module_exit(alsa_card_ens137x_exit),.

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論