黃 佳,胡 鋼,張 富,張宇翔
(1.河海大學計算機與信息學院,常州 213022;2.常州市傳感網與環境感知重點實驗室,常州213022;3.江蘇樂眾信息技術有限公司,常州 213022)
隨著廣播事業的不斷發展、節目頻道的增加以及服務用戶的不斷增多,在Android 智能終端上開發調頻廣播系統顯得日益重要。目前Android 智能終端上的廣播有兩種:一種是網絡廣播,無需硬件配置,依靠網絡電臺,接收網絡流媒體播放數據,但耗費的數據流量大,不僅移動網絡數據流量消費貴,而且我國目前Wifi 普及率較低,因此網絡廣播市場有限;另一種是嵌入式調頻廣播,依靠移動終端嵌入調頻廣播模塊來接收廣播電臺,由于未使用移動網絡數據包,消費相對低,深得消費者喜愛。本系統采用嵌入式的調頻廣播系統設計方法。
調頻廣播的軟硬件系統通過Linux 操作系統及其驅動程序聯系在一起。硬件系統包括應用處理器,調頻廣播接收模塊及音頻解碼器模塊。軟件系統是基于Android 平臺,采用Linux 操作系統,軟件核心技術應是解決最底層調頻廣播模塊的驅動程序開發、中間層的硬件抽象層接口和Java 本地調用函數設計,以及頂層調頻廣播播放器應用程序的設計。
系統硬件結構如圖1 所示。
本硬件系統采用主頻為1GHz、45nm 制程的數據處理芯片S5PC110 作為應用處理器,主要功能是為調頻廣播接收模塊和音頻編解碼器模塊提供控制信號。應用處理器直接向調頻廣播模塊提供32KHz的時鐘,并通過IIC 總線發送指令提供時鐘線(FM_SCL)和信號線(FM_SDA)來配置調頻廣播芯片的五種工作狀態。音頻編解碼器通過IIS 總線將數字音頻數據傳輸給應用處理器,應用處理器通過IIC總線控制音頻編解碼器的時序,設置采樣率及編碼比特率并配置好其通路以及AD、DA的工作模式。

圖1 硬件設計框圖
調頻廣播接收模塊由調頻廣播芯片RDA5820及帶通濾波器構成。該模塊的功能是接收射頻FM廣播信號并解調出模擬信號。帶通濾波器采用符合調頻廣播頻率范圍的并聯諧振電路,利用LC的諧振原理實現對射頻信號的選頻來達到濾波效果。RDA5820 采用數字低中頻架構,有復位初始化,設置頻點、搜臺、工作及休眠五種狀態。濾波后的信號進入該芯片,經過低噪聲放大器、正交圖像抑制混頻器、可編程增益控制后,進行模數轉換和音頻數字信號處理,再通過模數轉換得到兩路模擬信號——左聲道和右聲道廣播信號FM_OUTL FM_OUTR。這種混合信號架構利用DSP 執行通道選擇,調頻解調和立體音頻處理,MPX 譯碼自主完成從立體聲到單聲道的切換來限制輸出噪聲。音頻解碼器WM8994支持直接數字基帶連接并提供時鐘和數據多路復用器。由RDA5820 芯片接收工作時輸出的立體聲音頻信號連到WM8994 上的L 和R 音頻輸入端口,進行音頻解碼后,最終以耳機或擴音器的形式外放[1,4]。
系統的軟件設計基于Android 平臺,主要解決四個方面問題:添加內核層的調頻廣播驅動程序,用來驅動調頻廣播硬件設備;設計硬件抽象層(HAL)接口,用來對Linux 內核驅動程序的封裝,向上提供接口,屏蔽底層實現細節;實現Java 本地調用(JNI)機制,使得在Dalvik 虛擬機內部運行的Java 程序能夠與用其它編程語言(如C 和C ++)編寫的應用程序和庫進行交互操作;設計應用程序層的調頻廣播播放器應用,用來實現調頻廣播系統的應用[2]。軟件設計流程如圖2 所示。

圖2 軟件設計流程圖
編寫Android 系統Linux 內核層驅動程序,首先包含如#include <linux/i2c.h >、<linux/ioctl.h>等系統頭文件和"rda5820_fm_ctrl.h"自定義的頭文件。其關鍵設計如下:
(1)file_operations 結構體
file_operations 結構體是把系統調用和驅動程序關聯起來的關鍵數據結構。讀取file_operation 中相應的函數指針,把控制權轉交給函數,完成Linux 設備驅動程序的工作。
在系統內部,I/O 設備的存取操作通過特定的入口點進行,這組特定的入口點由設備驅動程序提供,由file_operations 結構體向系統說明,定義在include/linux/fs.h中[5]。本系統設計的調頻廣播的file_operation 結構體為:

使用這種語法提高了代碼的兼容性。其中open()函數為給定設備節點打開設備,ioct1()函數內是一個switch{case}結構,每一個開關語句對應一個命令碼,做出一些相應的操作,主要對搜臺、開始、停止、獲取頻道、音量設置進行處理,實現對調頻廣播設備I/O 通道的控制。
(2)驅動入口和出口函數
在入口函數_init rda5820_driver_init()中,利用i2c_static_add_device()函數向系統注冊rda5820_i2c_driver 設備;在出口函數_exit rda5820_driver_exit()中,使用i2c_unregister_device()函數向系統注銷rda5820_i2c_driver 設備,并用module_init()和module_exit()來指定驅動入口和出口函數[5]。
Android的硬件抽象層(HAL)是用來隔離Linux內核和Android 用戶空間的一個中間層。具體實現有兩種方式:一是沒有經過封裝,通過直接函數調用的方式來操作硬件驅動;二是通過HAL stub 來給上層提供一個統一的調用接口,只要在HAL 中實現這些接口,用戶層的代碼無需太大改動。本系統使用HAL Stub的方式來實現,由應用程序獲取并調用HAL stub 完成對硬件的控制,具有可移植性好的特點。
HAL的設計關鍵在于將三個結構體模塊類型hw_module_t、設備類型hw_control_device_t 和模塊方法hw_ module _methods_t 實例化,再交由HAL 內部機制調用。先用fm_module_t()函數繼承hw_module_t 結構,自定義針對調頻廣播控制的fm_control_ device_t()結構,其中包含hw_device_t 和支持的API 操作。
在HAL 實現了內部結構體之后,定義一個HAL模塊,賦予該模塊一個唯一的ID 值,用來向上層提供一個接口供其調用。該HAL 模塊為:

Java 本地調用(JNI)使得在Dalvik 虛擬機內部運行的Java 程序能夠與用C、C++編程語言編寫的應用程序和庫進行交互操作。JNI 函數設計流程如圖3 所示。

圖3 JNI 函數設計流程圖
其中hw_get_module()調用HAL 中內部結構體hw_methods_t。可供上層調用的功能函數包括調頻廣播的open()函數、getFrequency()函數、autoSearch()函數、getVolume()函數、setVolume()函數及close()函數。用JNINativeMethod fmMethods[]來表示映射關系,再通過編寫Android.mk 文件確定生成的庫文件,方便應用層調用。
調頻廣播系統的應用程序設計在Eclipse 環境中根據硬件所支持的功能和系統需求利用Java 語言進行開發。本系統選擇耳機線作為接收天線,是因為考慮到直接在PCB 上布線難,且對其他高頻信號產生干擾,而耳機線的長度與調頻廣播的半波長相當,能有效接收信號。在應用程序中涉及的關鍵點如下:定義全局變量HEADSET_STATE_PATH="/sys/class/headset/headset/status";/*系統內耳機的設備文件節點*/;boolean isHeadsetPlugIn()函數判斷耳機是否插入;getHeadsetState()函數取得系統得到的耳機狀態。使用Button、TextView 和Dialog組件實現對調頻廣播開始、自動搜臺、播放、手動搜臺、切換頻道及停止的功能調用。圖4為調頻廣播系統應用程序工作流程圖。圖5為調頻廣播播放器運行圖。
利用Android 系統開源特性設計的調頻廣播系統,可嵌入到手機、平板電腦、機頂盒、數字電視等其它終端設備,具有良好的移植和擴展性能。Android 系統在移動終端的應用將會逐步成熟和發展,產品價格也將最終接近大眾消費水平,屆時調頻廣播應用將成為人們休閑娛樂的必備工具。

圖4 應用程序工作流程圖

圖5 移動終端應用運行界面
[1]徐博堯,楊剛.一種基于ARM-Linux的調頻廣播監測接收機的設計[J].中國傳媒大學學報自然科學版,2010,17(2):76-80.
[2]Enck W,Ongtang M,McDaniel P.Understanding Android Security[J].Security & Privacy,IEEE.2009,7(1):50-57.
[3]劉淼.嵌入式系統接口設計與Linux 驅動程序開發[M].北京:北京航空航天大學出版社.2008.
[4]張文月,馬永濤,劉開華.DRM+調頻接收機數字信號處理部分研究與實現[J].電子測量技術,2011,34(12):16-19.
[5]Corbet Jonathan,Rubini Alessandro,Korah- Hartman Greq.Linux Device Drivers 3rd[M].Oreilly&Associates Inc.,2005.