VxWorks下基于CS4281聲卡的VOIP設計與實(shí)現
1 VxWorks及聲卡簡(jiǎn)介
VxWorks是由風(fēng)河(Wind River System Inc.)公司專(zhuān)門(mén)為實(shí)時(shí)嵌入式系統設計開(kāi)發(fā)的一套具有微內核、高性能、可伸縮的實(shí)時(shí)操作系統,為程序員提供了高效的實(shí)時(shí)任務(wù)高度、中斷管理,實(shí)時(shí)的系統資源以及實(shí)時(shí)的任務(wù)間通信,并能夠根據用戶(hù)的需求進(jìn)行組合。應用程序員可以將盡可能多的精力放在應用程序本身,而不必再去關(guān)心系統資源的管理。VxWorks是一種功能強大而且比較復雜的操作系統,VxWorks只占用了很小的存儲空間,并可高度裁減,保證了系統能以較高的效率運行。VxWorks的優(yōu)秀特性為編寫(xiě)應用程序和設備驅動(dòng)程序提供了極大的便利。在VxWorks下,設備驅動(dòng)程序既可以嵌入到內核中隨系統一起啟動(dòng),也可以作為可加載模塊在系統啟動(dòng)之后運行。本文的聲卡驅動(dòng)程序采用后一種方式。
本文選用的聲卡是Cirrus Logic公司的CS4281/AC′97。這是一款功能強大的聲卡,他主要由CS4281和C2S4297A芯片組成。CS4297A是符合AC′97(Audio Codec′97)規范的一個(gè)混合信號串行編解碼器。他負責對原始聲音信號的采樣混音處理,把接收的模擬聲音信號轉換成數字信號;也將接收的數字音頻信號通過(guò)一種特殊的音頻算法轉換成模擬信號。CS4281是一個(gè)PCI-Ac′97數字控制器,他提供串行AC′97編解碼器(如CS4297A)與并行PCI總線(xiàn)之間的接口。
2 總體設計
程序劃分為兩個(gè)模塊:(1) CS4281聲卡的VxWorksPCI驅動(dòng),實(shí)現聲音的錄音和播放;(2) 通信模塊,該模塊負責接收驅動(dòng)模塊的聲音數據,并打包通過(guò)以太網(wǎng)發(fā)送;接收以太網(wǎng)的數據,解包成聲音數據傳給驅動(dòng)模塊。
低層是聲卡驅動(dòng):從麥克風(fēng)進(jìn)來(lái)的聲音在這里記錄,并發(fā)送PCM抽樣聲音數據到上層;同時(shí),聲音數據從上層傳來(lái)并發(fā)送到聲卡播放,通過(guò)耳機輸出。主要有以下幾個(gè)函數:PCI配置空間的分配,完成聲卡的查找及內存映射;CS428l及CS4297的初始化,進(jìn)行一系列的硬件初始化;DMA緩沖區的分配,用來(lái)緩存聲卡驅動(dòng)和通信模塊之間的聲音數據;取樣率和格式的設置,選擇合適的取樣率及格式;聲音系統的打開(kāi)及關(guān)閉,控制錄音及播放功能的開(kāi)關(guān);中斷處理函數,聲卡驅動(dòng)和通信模塊之間通過(guò)中斷來(lái)進(jìn)行數據的存取。
上層是通信部分:聲音數據在這里打包成分組通過(guò)網(wǎng)卡發(fā)送出去,從網(wǎng)卡接收來(lái)的數據在此解包并交給聲卡驅動(dòng),數據經(jīng)過(guò)以太網(wǎng)的發(fā)送和接收通過(guò)調用Socket來(lái)實(shí)現。
2.1 確定取樣率
結合實(shí)際的實(shí)驗環(huán)境,從諸多的取樣率和格式中,選擇11025 Hz取樣頻率、8 b單聲道。計算最低的數據傳輸率:
2.2 設置緩沖區
如果網(wǎng)絡(luò )中通信量變化較大,將產(chǎn)生時(shí)延抖動(dòng)。需要設置兩個(gè)緩沖區用來(lái)在發(fā)送數據和接收數據時(shí)進(jìn)行緩存,以減輕時(shí)延抖動(dòng)的影響,保證通信質(zhì)量。緩沖區大小應適當,如果太小,將會(huì )造成數據丟失;如果太大,抖動(dòng)時(shí)延將增長(cháng)。
在x86結構中,頁(yè)面大小是4 kB。這對DMA緩沖大小是個(gè)限制,因為DMA需要位于一個(gè)內存頁(yè)面中來(lái)保持緩沖區的連續性,且要適應基于UDP的Socket通信,我們確定播放DMA緩沖和錄音DMA緩沖大小都為2 kB,并且用“乒乓”技術(shù)在這兩個(gè)緩沖區間傳輸,那么每1 kB,將有一個(gè)播放中斷和錄音中斷。1 s中的中斷次數為:111k/1k△11。
3 聲卡驅動(dòng)程序
3.1 PCI局部總線(xiàn)
本文所選用的聲卡是Cirrus Logic公司的CS4281/AC′97 PCI聲卡,作為一個(gè)PCI設備,在設備的初始化階段,他和一般的PCI設備的步驟相同。
每一個(gè)PCI總線(xiàn)設備都有一個(gè)配置寄存器空間,他使目標設備的配置簡(jiǎn)單易行。配置空間是一個(gè)容量為256 B并具有特定結構的地址空間。配置寄存器是PCI設備的硬件與PCI設備的初始化軟件及錯誤處理軟件之間的信息交換區,以便軟件對PCI設備進(jìn)行識別和控制以及PCI設備向軟件反映設備狀態(tài)和要求。該空間分為頭標區和設備關(guān)聯(lián)區兩部分。一個(gè)設備的配置空間不僅在系統自舉時(shí)可以訪(fǎng)問(wèn),而且在其他時(shí)間內也可以訪(fǎng)問(wèn)。
3.2 聲卡的驅動(dòng)結構及流程
(1) 聲卡的探測以及入口
VxWorks BSP在syslib.c中探測并初始化系統中的PCI設備,檢測設備的I/O映射地址,內存映射地址以及中斷向量和級別,這些硬件參數對于主芯片的讀寫(xiě)和掛接中斷起到至關(guān)重要的作用。因此,在這里加入聲卡的探測模塊。然后將探測到的參數傳遞給驅動(dòng)程序入口函數。
在聲卡的探測模塊中,利用的是CS4281/AC′97的廠(chǎng)商標識和設備標識,得到他的功能號、總線(xiàn)號和設備號.然后配置他的PCI配置空間,將聲卡的寄存器映射。最后得到聲卡內存映射基地址以及中斷向量和級別。
(2) 入口函數
入口函數主要完成CS4281控制芯片和CS4297編解碼芯片的初始化,DMA緩沖區內存分配,設置采樣率和格式及掛接中斷等任務(wù)。
CS4281芯片的初始化要嚴格按照文獻[4]的說(shuō)明順序進(jìn)行。CS4297編解碼芯片的初始化主要完成耳機和麥克風(fēng)的選擇、打開(kāi),音量設置等任務(wù),涉及到的寄存器有PCM_OUT_VOLUME,MASTER_VOLUME,HEAD-PHONE_VOLUME,GENERAL_PURPOSF,MICRO-PHONE_VOLUME,INPUT_MUX_SELECT,RE-CORD_GAIN,GENERAL_PURPOSE。為DMA播放和錄音緩沖區分配連續的2 kB內存空間,把分配的內存空間基地址寫(xiě)入DMA基地址寄存器。在本文中,我們選擇的是8 b單聲道格式和11 025 Hz取樣頻率,經(jīng)過(guò)計算,把相應的值寫(xiě)入DMA引擎模式寄存器,把采樣率寫(xiě)人DACSR和ADCSR。最后利用探測模塊中取得的中斷向量和中斷級把中斷號和中斷處理函數掛接在一起。
(3) 聲音系統的啟動(dòng)和關(guān)閉
該模塊主要完成錄音的開(kāi)啟和關(guān)閉、播放的開(kāi)啟和關(guān)閉。錄音的開(kāi)啟即把0寫(xiě)入DMA引擎控制寄存器1中的MSK位,且使能中斷;錄音的關(guān)閉即把1寫(xiě)入DMA引擎控制寄存器1中的。MSK位。播放的開(kāi)啟即把0寫(xiě)人DMA引擎控制寄存器0中的MSK位,且使能中斷;播放的關(guān)閉即把1寫(xiě)入DMA引擎控制寄存器0中的MSK位。
(4) 中斷處理程序
CS4281有一個(gè)中斷狀態(tài)寄存器和一個(gè)中斷屏蔽寄存器,他們對應位意義相同。中斷狀態(tài)寄存器反映了聲卡能產(chǎn)生的幾種中斷。一旦有中斷發(fā)生,分析中斷狀態(tài)寄存器,判斷中斷類(lèi)型,再做相應的處理。根據我們的設計,如果是播放中斷則釋放播放信號量,促使上層軟件拷貝聲音數據至下層軟件;如果是錄音中斷則釋放錄音信號量,促使上層軟件從下層軟件取走已到達的聲音數據。最后設置中斷結束標志。
(5) 播放和發(fā)送時(shí)的數據流
播放時(shí)的數據流。聲卡中的播放緩沖(上文中所設的DMA緩沖)和FIFO0(從格式化器formatter接收聲音數據,按先入先出方式存儲,供CS4297芯片播放)之間數據傳輸由DMA0控制。DMA0引擎盡量保持FIFO0滿(mǎn)。播放緩沖是個(gè)2 kB的內存,他的起始地址被寫(xiě)進(jìn)DMA0基地址寄存器(DBA0)。2 047 B(計數應比所分配的字節數小1,因為中斷發(fā)生于roll-unders模式下)寫(xiě)入DMA0基本計數寄存器(DBC0),DMA0引擎控制從播放緩沖中讀入的字節數。當播放緩沖半空或空,將產(chǎn)生一個(gè)中斷,促使從上層軟件取數據。
錄音時(shí)的數據流。聲卡中的錄音緩沖和FIFO1(從CS4297芯片接收聲音數據,按先入先出方式存儲,傳給格式化器formatter)之間數據傳送受控于DMA1。DMA1引擎盡量保持FIFO1為空,他同樣也計算寫(xiě)進(jìn)錄音緩沖的字節數。當錄音緩沖半滿(mǎn)或滿(mǎn),將產(chǎn)生一個(gè)中斷,促使上層軟件把數據取走。
4 UDP通信
4.1 UDP協(xié)議
在以太網(wǎng)設施基礎上,VxWorks使用因特網(wǎng)組件TCP/IP提供的端到端的傳輸能力在位于不同的主機上的任務(wù)間傳輸用戶(hù)數據。在VxWorks中,使用Socket作為應用程序和TCP/IP協(xié)議的接口。Socket有2種基本類(lèi)型:可靠的數據流SOCK_STREAM,使用TCP協(xié)議;數據報SOCK_DGRAM,使用UDP協(xié)議。
UDP相對于TCP有以下一些優(yōu)點(diǎn)[2]:
(1) UDP的報文短,利于減小傳輸時(shí)延;
(2) UDP是無(wú)連接協(xié)議,發(fā)送數據前不需要建立連接,適合于聲音數據這種實(shí)時(shí)性要求高的應用;
(3) UDP沒(méi)有擁塞控制,因此網(wǎng)絡(luò )出現的擁塞不會(huì )使源主機的發(fā)送速率降低。
UDP的這些優(yōu)點(diǎn)對于聲音數據的實(shí)時(shí)傳輸非常重要,這些優(yōu)點(diǎn)將保證傳輸盡可能有一個(gè)短時(shí)延、恒定的速度,因此選擇UDP。
在無(wú)連接的Socket中,在通信的兩端分別創(chuàng )建客戶(hù)機端和服務(wù)器端,通信雙方在整個(gè)過(guò)程中是平等的,雙方直接通過(guò)Socket調用來(lái)發(fā)送或接收數據報。
UdpClient模塊:創(chuàng )建客戶(hù)端Socket;初始化服務(wù)器端地址;FOREVER{調用UDP發(fā)送模塊;發(fā)送數據到服務(wù)器}。
UdpServer模塊:創(chuàng )建本地地址;創(chuàng )建服務(wù)器端Sock-et;把Socket和本地地址綁定起來(lái);FOREVER{接收數據;調用UDP接收模塊)。
4.2 UDP發(fā)送
發(fā)送模塊等待錄音信號量。如果獲得,表示一些新的數據在錄音緩沖中已有效。將把新數據從錄音緩沖拷入上層軟件存儲區,然后通過(guò)Socket把他發(fā)送到另一端主機。如果上層軟件中的存儲區滿(mǎn),丟棄舊分組存入新分組。
4.3 UDP接收
接收模塊等待從Socket來(lái)的數據。如果獲得播放信號量,表示播放緩沖區中的數據已被播放,將把上層軟件存儲區中的數據拷入播放緩沖;否則,任務(wù)將被掛起。如果上層軟件中的存儲區滿(mǎn),丟棄舊分組存入新分組。
5 遇到的主要問(wèn)題
在本文所搭建的環(huán)境中,能較好地實(shí)現兩塊聲卡之間的通話(huà)。開(kāi)發(fā)過(guò)程中,主要遇到兩個(gè)問(wèn)題:
(1) 聲卡中沒(méi)有聲音數據。聲卡的FIFO緩沖區及DMA緩沖區中均沒(méi)有數據。經(jīng)分析查出:CS4297芯片中關(guān)于耳機和麥克風(fēng)的寄存器沒(méi)有打開(kāi)和選中,耳機和麥克風(fēng)一直處于“mute”狀態(tài)。關(guān)掉"mute'’后,問(wèn)題解決。
(2) 不能產(chǎn)生中斷。DMA緩沖區中已有數據,根據程序設計,此時(shí)應產(chǎn)生中斷,由上層通信模塊取走聲音數據,但中斷一直不能產(chǎn)生。經(jīng)分析原因為:在聲卡探測程序段獲得的中斷級直接用作中繼號來(lái)掛接中斷。解決方法:通過(guò)中斷級來(lái)獲取中斷向量,再獲取中斷號,用來(lái)掛接中斷處理程序。
評論