版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1Linux ALSA聲卡驅(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)介架構(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和多線(xiàn)程提供應(yīng)用程序開(kāi)發(fā)庫(kù)兼容OSS應(yīng)用程序開(kāi)發(fā)5一、 ALSA架構(gòu)簡(jiǎn)介ALSA是Advanced Linux Sound Architecture,高級(jí)Linux聲音架構(gòu)的簡(jiǎn)稱(chēng),它在Linux操作系統(tǒng)上提供了音頻和MIDI(Musica
2、l Instrument Digital Interface,音樂(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)行寫(xiě)程序不需要打開(kāi)設(shè)備等操作,所以編程人員在寫(xiě)程序的時(shí)候不會(huì)被底層的東西困擾。ALSA自帶的應(yīng)用程序是alsa-utils工具包,包括aplay、alsamixer等。aplay用于在A(yíng)SLA上播放音頻。alsamixer用于改變音頻信號(hào)的音量。alsa-lib是用戶(hù)空間的函數(shù)庫(kù),提供了libasound.so給應(yīng)用程序使用,應(yīng)用程
3、序應(yīng)包含頭文件asoundlib.h。這個(gè)庫(kù)通過(guò)提供封裝函數(shù)(ALSA-API),使ALSA應(yīng)用程序編寫(xiě)起來(lái)更容易。alsa-lib中有control,timer,dmix,pcm等,都是以插件(plugin)的形式存在的。alsa-lib通過(guò)硬件訪(fǎng)問(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)硬件操縱訪(fǎng)問(wèn)的功能,這也是聲卡驅(qū)動(dòng)程序中用戶(hù)需實(shí)現(xiàn)的主要部分; (2)中間層是ASLA驅(qū)動(dòng)的核心部分,它由各種功能的音頻設(shè)備組件構(gòu)成,為用戶(hù)提供了一些預(yù)定義組件(如PCM、
4、AC97、音序器和控制器等),另外用戶(hù)也可以自行定義設(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)用層勾畫(huà)出了彼此之間的關(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)系。用戶(hù)層的alsa-lib通過(guò)操作alsa-driver創(chuàng)建的設(shè)備文件/dev/sn
5、d/pcmC0D0p等對(duì)內(nèi)核層進(jìn)行訪(fǎng)問(wèn)。內(nèi)核層的alsa-drivier驅(qū)動(dòng)再經(jīng)由sound core對(duì)硬件聲卡芯片進(jìn)行訪(fǎng)問(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)、目的、方法二、最佳實(shí)踐的目標(biāo)、目的、方法三、具體步驟四、總結(jié)9二、最佳實(shí)踐的目標(biāo)、目的、方法在alsa的整體架構(gòu)中,alsa-driver的硬件操控層,負(fù)責(zé)實(shí)現(xiàn)硬件操縱訪(fǎng)問(wèn),這也是聲卡驅(qū)動(dòng)程序中用戶(hù)需實(shí)現(xiàn)的主要部分。我們要實(shí)現(xiàn)的是針對(duì)特定聲卡芯片ens1371的控制
6、在這里把它叫做device-driver(設(shè)備驅(qū)動(dòng)), alsa-driver的其它部分叫做alsa-driver(alsa驅(qū)動(dòng))。user spacekernel space app 1app nALSA應(yīng)用程序alsa-libpcmdmixcontroltimeralsa-driveralsa內(nèi)核APIdevice-driverhardwareens1371ALSA整體架構(gòu)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)境是否能夠正常播放音
7、頻。如果不能播放,可以用alsamixer等工具查看音量是否被靜音了??傊?,如果正常環(huán)境如果都不能播放音頻,那我們后續(xù)的工作也就不能檢驗(yàn)正確與否了。 aplay工具shell中命令如下: # apt-get install alsa-utils /初次使用安裝alsa-utils工具,以后直接執(zhí)行下一步就可以了。 # aplay /opt/test_files/pcm.wav /aplay后面的文件路徑根據(jù)自己的實(shí)際情況填寫(xiě)。紅色文字表示shell中輸入的命令。 alsamixer工具shell中命令如下: # apt-get install alsa-utils /初次使用安裝alsa-ut
8、ils工具,以后直接執(zhí)行下一步就可以了。 # alsamixer。alsamixer中,、 方向鍵可以調(diào)整焦點(diǎn),、方向鍵可以調(diào)整音量,esc鍵退出。也可以用數(shù)字或+、-鍵調(diào)整音量。 (2) 檢查使用的PC的聲卡是否是ENS1371,shell中命令如下: # lspci |grep “1371” ENS1371聲卡會(huì)顯示類(lèi)似如下字樣 #02:02.0 Multimedia audio controller: Ensoniq ES1371 AudioPCI-97 (rev 02) 如果不是ENS1371,下文可作為參考根據(jù)自己的實(shí)際情況進(jìn)行。12三、具體步驟1. 準(zhǔn)備工作。 (2) 新建工作目錄
9、如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è)編寫(xiě)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/mod
10、ules/uname -r/buildmodules:make -C $(KBUILD) M=$(shell pwd) modulesclean:rm -f *.o * core .depend .*.cmd *.ko *.mod.c *.order *.symversrm -rf .tmp_versionsendif#define CHIP1371#include ens1370.c“13三、具體步驟3. 抽取ens1370.c(位于linux-source-2.6.26/sound/pci)中Linux通用驅(qū)動(dòng)程序核心,添加到ens1371-playback.c中并make,測(cè)試??梢韵忍?/p>
11、加框架,再向框架中逐步添加函數(shù)。可以打印適當(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ù)外,其他部分的最好用注釋?zhuān)灰苯觿h除,以便在后面檢查是否刪除了有用的部分。 定義最小化的函數(shù)后,代碼是可以編譯,并可以加載到內(nèi)核的,再逐步添
12、寫(xiě)被調(diào)用函數(shù),以此類(lèi)推,直到所有的調(diào)用關(guān)系全部被添加進(jìn)代碼。如向init和exit中添加實(shí)現(xiàn)函數(shù):#define CHIP1371#include #define ENS1371_DEBUG#ifdef ENS1371_DEBUG#define FUNC_LOG() printk(KERN_ERR “FUNC_LOG: %d%s()n, _LINE_, _FUNCTION_)#endifstatic int _init alsa_card_ens137x_init(void) FUNC_LOG();static void _exit alsa_card_ens137x_exit(void) F
13、UNC_LOG();module_init(alsa_card_ens137x_init)module_exit(alsa_card_ens137x_exit)14#define CHIP1371#include #include #define ENS1371_DEBUG#ifdef ENS1371_DEBUG#define FUNC_LOG() printk(KERN_ERR FUNC_LOG: %d:%s()n, _LINE_, _FUNCTION_)#endif#define DRIVER_NAME ENS1371“static struct pci_device_id snd_aud
14、iopci_ids = /#ifdef CHIP1370/ 0 x1274, 0 x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, ,/* ES1370 */#endif#ifdef CHIP1371 0 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,
15、0, 0, ,/* Ectiva EV1938 */#endif 0, ;static int _devinit snd_audiopci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)FUNC_LOG();return 0;static void _devexit snd_audiopci_remove(struct pci_dev *pci)FUNC_LOG();static struct pci_driver driver = .name = DRIVER_NAME,.id_table = snd_audiop
16、ci_ids,.probe = snd_audiopci_probe,.remove = _devexit_p(snd_audiopci_remove),#ifdef CONFIG_PM/.suspend = snd_ensoniq_suspend,/.resume = snd_ensoniq_resume,#endif;static int _init alsa_card_ens137x_init(void)FUNC_LOG();return pci_register_driver(&driver);static void _exit alsa_card_ens137x_exit(v
17、oid)FUNC_LOG();pci_unregister_driver(&driver);module_init(alsa_card_ens137x_init)module_exit(alsa_card_ens137x_exit)三、具體步驟15三、具體步驟5. make、insmod、rmmod 驅(qū)動(dòng)模塊示例:注意insmod ens1371-playback.ko前,要先卸載系統(tǒng)中原有的ens1371模塊snd_ens1371。否則,在定義了DRIVER_NAME后,insmod時(shí)就會(huì)出錯(cuò)。圖中,紅色是shell中輸入的命令,黃色是系統(tǒng)打印的信息,而綠色是我們的模塊打印的log。
18、另外,驅(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()類(lèi)似,如此一級(jí)一級(jí)的填充下去,直至模塊可以播放出聲音。 對(duì)于snd_audiopci_probe()這樣比較復(fù)雜的函數(shù),要一行一行的添加,邊添加邊調(diào)試。如遇到變量等應(yīng)該在前面函數(shù)中賦值而還沒(méi)有實(shí)現(xiàn)的部分,可以先用if宏等方法暫時(shí)注釋掉,如下頁(yè)代碼中的紅色部分。添加的代碼如下:#define
19、 CHIP1371#include #include #include #include #define ENS1371_DEBUG#ifdef ENS1371_DEBUG#define FUNC_LOG() printk(KERN_ERR FUNC_LOG: %d:%s()n, _LINE_, _FUNCTION_)#endif#define DRIVER_NAME ENS1371“static struct pci_device_id snd_audiopci_ids = ;static int indexSNDRV_CARDS = SNDRV_DEFAULT_IDX;/* Index 0
20、-MAX */static char *idSNDRV_CARDS = SNDRV_DEFAULT_STR;/* ID for this card */static int enableSNDRV_CARDS = SNDRV_DEFAULT_ENABLE_PNP;/* Enable switches */static int spdifSNDRV_CARDS;static int lineioSNDRV_CARDS;struct ensoniq ;MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);static int _devinit snd_ensoniq
21、_1371_mixer(struct ensoniq *ensoniq, int has_spdif, int has_line)FUNC_LOG();return(0);static int _devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device, struct snd_pcm * rpcm)FUNC_LOG();return 0;static int _devinit snd_ensoniq_create(struct snd_card *card, struct pci_dev *pci, struct ensoniq
22、* rensoniq)FUNC_LOG();return 0;17三、具體步驟6. 代碼續(xù):static int _devinit snd_audiopci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)static int dev;struct snd_card *card;struct ensoniq *ensoniq;int err, pcm_devs2;FUNC_LOG();if (dev = SNDRV_CARDS)return -ENODEV;if (!enabledev) dev+;return -EN
23、OENT;card = snd_card_new(indexdev, iddev, THIS_MODULE, 0);if (card = NULL)return -ENOMEM;if (err = snd_ensoniq_create(card, pci, &ensoniq) private_data = ensoniq;pcm_devs0 = 0; pcm_devs1 = 1;/#ifdef CHIP1370/if (err = snd_ensoniq_1370_mixer(ensoniq) 0) /snd_card_free(card);/return err;/#endif/#i
24、fdef CHIP1371if (err = snd_ensoniq_1371_mixer(ensoniq, spdifdev, lineiodev) 0) snd_card_free(card);return err;/#endifif (err = snd_ensoniq_pcm(ensoniq, 0, NULL) 0) snd_card_free(card);return err;/if (err = snd_ensoniq_pcm2(ensoniq, 1, NULL) 0) /snd_card_free(card);/return err;/if (err = snd_ensoniq_
25、midi(ensoniq, 0, NULL) driver, DRIVER_NAME);strcpy(card-shortname, Ensoniq AudioPCI);#ifdef ENS1371_RESERVEDsprintf(card-longname, %s %s at 0 x%lx, irq %i,card-shortname,card-driver,ensoniq-port,ensoniq-irq);#endifif (err = snd_card_register(card) 0) snd_card_free(card);return err;pci_set_drvdata(pc
26、i, card);dev+;return 0;static void _devexit snd_audiopci_remove(struct pci_dev *pci)FUNC_LOG();snd_card_free(pci_get_drvdata(pci);pci_set_drvdata(pci, NULL);static struct pci_driver driver = .name = DRIVER_NAME,.id_table = snd_audiopci_ids,.probe = snd_audiopci_probe,.remove = _devexit_p(snd_audiopci_remove),#ifdef CONFIG_PM/.suspend = snd_ensoniq_suspend,/.resume = snd_ensoniq_resume,#endif;static int _init alsa_card_ens137x_init(void)FUNC_LOG();return pci_register_driver(&driver);static void _exit alsa_card_ens137x_exit(void)FUNC_LOG();pci_un
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 感恩講話(huà)稿(資料15篇)
- 感恩母親講話(huà)稿(21篇)
- 愚人節(jié)創(chuàng)意活動(dòng)策劃方案3篇
- 寶寶周歲慶典講話(huà)稿
- 意外保險(xiǎn)基礎(chǔ)知識(shí)
- 智研咨詢(xún)發(fā)布:2024年中國(guó)氮化硼行業(yè)市場(chǎng)現(xiàn)狀、發(fā)展概況、未來(lái)前景分析報(bào)告
- 2024年中國(guó)熔鹽閥行業(yè)發(fā)展策略、市場(chǎng)環(huán)境及前景研究分析報(bào)告
- 吸氧治療流程圖解
- 拿下試卷的秘密武器
- 腹腔鏡結(jié)直腸癌根治術(shù)中改良體位擺放對(duì)體位并發(fā)癥的影響
- 《梅大高速茶陽(yáng)路段“5·1”塌方災(zāi)害調(diào)查評(píng)估報(bào)告》專(zhuān)題警示學(xué)習(xí)
- 2024年09月北京中信銀行北京分行社會(huì)招考(917)筆試歷年參考題庫(kù)附帶答案詳解
- 2024年公司領(lǐng)導(dǎo)在新年動(dòng)員會(huì)上的講話(huà)樣本(3篇)
- 人教版道德與法治二年級(jí)下冊(cè)《第一單元 讓我試試看》大單元整體教學(xué)設(shè)計(jì)2022課標(biāo)
- 2024年3季度青島房地產(chǎn)市場(chǎng)季度簡(jiǎn)報(bào)
- 蘇東坡詞十首
- 2023年天津市文化和旅游局直屬事業(yè)單位招聘考試真題及答案
- 電力系統(tǒng)分析(郝亮亮)
- 常州市2023-2024學(xué)年八年級(jí)上學(xué)期期末地理試卷(含答案解析)
- 道路安全教育課件
- 2023年浙江省衢州市中考語(yǔ)文試題(含答案解析)
評(píng)論
0/150
提交評(píng)論