牟 躍,周淵平
(四川大學(xué) 電子信息學(xué)院, 四川 成都 610065)
基于Android電話撥號功能的驅(qū)動設(shè)計
牟 躍,周淵平
(四川大學(xué) 電子信息學(xué)院, 四川 成都 610065)
由于Android操作系統(tǒng)開放源碼,在近幾年被廣泛用于各個領(lǐng)域,可以利用Android系統(tǒng)的開放性,開發(fā)該系統(tǒng)在有線電話方面的應(yīng)用。將Android平臺與撥號芯片MT8880結(jié)合起來研究。因為Android原生代碼具有很大局限性,支持的設(shè)備太少,所以為了識別MT8880這個特定設(shè)備,并控制MT8880的邏輯輸出,需要在Linux內(nèi)核中添加驅(qū)動模塊,并在HAL層和JNI層生成動態(tài)鏈接庫,使得頂層應(yīng)用程序可以控制撥號芯片MT8880。MT8880芯片主要用于發(fā)送雙音多頻信號(Dual Tone Multi Frequency),在加載了撥號驅(qū)動和應(yīng)用程序后,可以實現(xiàn)Android系統(tǒng)的撥號功能。經(jīng)測試,設(shè)計的撥號驅(qū)動能實現(xiàn)對新增設(shè)備的控制,電話應(yīng)用能成功撥號。
Android;Linux內(nèi)核; HAL; JNI;MT8880芯片
圖1 系統(tǒng)框架圖
Android是由Google公司和開放手機聯(lián)盟領(lǐng)導(dǎo)及開發(fā)、基于Linux內(nèi)核的開放源代碼的操作系統(tǒng)[1]。Android最近幾年發(fā)展迅猛,被用于各種場合。TQ210開發(fā)板搭載的是Android4.0系統(tǒng),使用的是三星公司生產(chǎn)的S5PV210處理器,能夠滿足大多數(shù)應(yīng)用場合的需求。而采用的撥號芯片MT8880能夠發(fā)送經(jīng)過濾波處理過的雙音多頻(Dual Tone Multi Frequency,DTMF)信號。
電話由于其信號穩(wěn)定、抗干擾能力強、輻射小等優(yōu)點被廣泛用于企業(yè)、事業(yè)機構(gòu)和個人。在如今移動設(shè)備被各個行業(yè)廣泛應(yīng)用的大環(huán)境下,可以通過底層驅(qū)動的開發(fā)[2],使得Android可以識別外部新增設(shè)備。將Android平臺與撥號芯片MT8880結(jié)合研究,可以實現(xiàn)Android電話撥號功能。
1.1 硬件框架
Android開發(fā)平臺(TQ210開發(fā)板)和MT8880撥號芯片構(gòu)成了硬件系統(tǒng)的主要部分[3],如圖1所示。Android平臺采用 TQ210 開發(fā)板, TQ210開發(fā)板的核心板為63 mm×53 mm×7 mm的10層板,共有280根引腳。核心板引出了兩路攝像頭接口CAMERA_A和CAMERA_B,其中CAMERA_B主要是開發(fā)板為滿足不同開發(fā)需求預(yù)留的應(yīng)用接口,可GPIO口復(fù)用,當(dāng)不用攝像頭功能時,可作為GPIO擴展口。Android的 GPIO接口連接MT8880撥號芯片,使用CAMERA_B的GPIO口與芯片的相應(yīng)管腳相連接,并通過GPIO口輸出高低邏輯電平,對芯片進(jìn)行控制,實現(xiàn)發(fā)送DTMF信號的功能。
1.2 語音撥號芯片MT8880
MT8880芯片采用ISO-CMOS技術(shù)制造,具有功耗低和穩(wěn)定性高等特點,能夠比較準(zhǔn)確地發(fā)送DTMF信號。MT8880的發(fā)送部分的內(nèi)部邏輯如圖2所示。從結(jié)構(gòu)上看,在發(fā)送與電話號碼對應(yīng)的DTMF信號之前,必須對寄存器進(jìn)行相應(yīng)操作,首先選擇對狀態(tài)寄存器SR和控制寄存器CRA進(jìn)行操作,打開信號音突發(fā)選通電路,使芯片能夠輸出信號,然后通過控制寄存器CRB和發(fā)送數(shù)據(jù)寄存器TDR,使得電話號碼能夠通過D1~D4數(shù)據(jù)線輸入,最后經(jīng)過行、列計數(shù)器和D/A轉(zhuǎn)換器,輸出DTMF信號。通過RSO及WR和RD口線可對相關(guān)寄存器進(jìn)行選擇和控制,具體控制功能的實現(xiàn)如表1。 從外部看,可以通過外部微處理器訪問其內(nèi)部的寄存器,以實現(xiàn)DTMF信號的發(fā)送功能。
圖2 MT8880發(fā)送部分內(nèi)部結(jié)構(gòu)框圖
RSOWRRD功能001寫發(fā)送數(shù)據(jù)寄存器10讀接收數(shù)據(jù)寄存器101寫控制寄存器10讀狀態(tài)寄存器
2.1 Android源碼編譯環(huán)境的搭建
首先在64位的Ubuntu12.04操作系統(tǒng)中,完成Android源碼的編譯操作,并在系統(tǒng)中安裝和配置JDK,而為了順利編譯Android源碼,在系統(tǒng)中還需要安裝GCC編譯器、相關(guān)的庫和交叉編譯器arm-linux-gcc。在完成編譯環(huán)境的搭建后,目標(biāo)代碼便能在其他平臺上運行。
2.2 撥號功能的軟件框架
Android的系統(tǒng)架構(gòu)與其操作系統(tǒng)一樣,采用了分層架構(gòu),主要包括應(yīng)用程序?qū)印?yīng)用程序框架層、系統(tǒng)運行庫和核心層[4],如圖3所示。為使Android可以識別撥號芯片MT8880這個特定的新增設(shè)備,即通過頂層代碼實現(xiàn)對硬件設(shè)備的控制,首先在Linux內(nèi)核實現(xiàn)了名為tel.c的內(nèi)核驅(qū)動,為系統(tǒng)上層提供了操作底層硬件的接口;然后在HAL層封裝控制邏輯,在JNI層將本地代碼封裝成上層應(yīng)用可以調(diào)用的Java代碼,并生成相應(yīng)的動態(tài)鏈接庫文件即.so文件;最后頂層便可通過調(diào)用動態(tài)鏈接庫,實現(xiàn)撥號功能。
圖3 系統(tǒng)軟件框架圖
2.2.1 底層驅(qū)動設(shè)計
底層驅(qū)動模塊主要是控制CAMERA_B上的GPIO管腳,提供控制MT8880撥號芯片硬件設(shè)備接口的邏輯電平,使得系統(tǒng)能夠控制外部芯片MT8880實現(xiàn)撥號。撥號驅(qū)動程序tel.c采用的混雜型驅(qū)動設(shè)備miscdevice,主要由設(shè)備的注冊misc_register、注銷misc_deregister、打開open、關(guān)閉close等部分組成。驅(qū)動程序tel.c通過宏S3C_GPIO_SFN(x)對管腳功能進(jìn)行定義,當(dāng)x為0時,管腳為輸入,x為1時,管腳為輸出;通過函數(shù)int s3c_gpio_setpull(unsigned int pin, amsung_gpio_pull_t pull)為指定的GPIO管腳配置上下位狀態(tài);通過函數(shù)int gpio_request(unsigned gpio, const char *label)向內(nèi)核申請管腳,并用label去描述它;通過函數(shù)void gpio_free(unsigned gpio)釋放一個已經(jīng)申請的引腳,此函數(shù)與gpio_request對應(yīng);通過函數(shù)int gpio_direction_output(unsigned gpio, int value )在管腳處輸出一個電平value(0或者1);通過函數(shù)int gpio_direction_input(unsigned gpio)讀??;通過函數(shù)static unsigned int gpio_cfg_table[]定義了gpio_table數(shù)組,這個數(shù)組用來定義電話驅(qū)動所用的GPIO引腳,總共需要7個引腳,分別為GPI0的0~6口。
2.2.2 驅(qū)動的編譯與安裝
將底層驅(qū)動程序tel.c文件編寫好后放入到/driver/char/mydrivers目錄下,并修改該目錄下的Kconfig和Makefile文件。由于使用動態(tài)加載驅(qū)動程序,所以必須先通過make menuconfig和make modules命令生成.ko文件,運行以上兩個命令后其編譯結(jié)果如圖4所示。 然后使用adb devices和adb push命令將tel.ko文件傳送到開發(fā)板上,并通過adb shell 命令進(jìn)入到Android Shell命令模式,即切換到開發(fā)板,最后使用insmod 命令將tel.ko模塊加載到開發(fā)板上。使用以上命令后,其編譯結(jié)果如圖5所示。
圖4 生成模板并傳遞到開發(fā)板上
圖5 加載模塊
2.3 HAL層軟件
硬件抽象層(Hardware Abstraction Layer,HAL)位于Linux內(nèi)核上面一層[5],其具體位置如圖6所示。HAL層主要用于隱藏底層驅(qū)動的業(yè)務(wù)邏輯,即頂層調(diào)用底層驅(qū)動的具體細(xì)節(jié),這樣就能夠擺脫Linux開源束縛,使關(guān)于驅(qū)動開發(fā)的具體細(xì)節(jié)不用公開,得到保護。
圖6 新HAL架構(gòu)
編譯 HAL 層庫文件方法如下:
(1)首先在 hardware/libhardware/include 目錄下創(chuàng)建tel.h 頭文件。tel.h頭文件主要用于定義hw_module_t、hw_device和hw_module_methods這三個重要的關(guān)系緊密的結(jié)構(gòu)體。tel.h也為HAL模塊定義了一個ID,通過這個ID來查找tel的HAL模塊。
(2)然后需要在device/embedsky/tq21目錄下創(chuàng)建名為libwiretelephone的文件夾,在該文件夾中添加tel.c、Android.mk 兩個文件。在HAl層實現(xiàn)了所有撥號驅(qū)動的業(yè)務(wù)邏輯, 在HAL層通過對GPIO口的控制實現(xiàn)對MT8880撥號芯片發(fā)送部分的控制,使芯片能夠發(fā)出雙音多頻(DTMF)信號。
(3)運行mmm device/embedsky/tq210/libtel命令生成tel.tq210.so文件,然后將文件復(fù)制到開發(fā)板上的/system/lib/hw目錄。最后通過adb device命令和adb push命令將tel.tq210.so文件加載到開發(fā)板上[6],運行以上命令后,編譯結(jié)果如圖7所示。
圖7 編譯 HAL 層庫文件
2.4 JNI層軟件
JNI(Java Native Interface)層指的是本地編程接口[7],其工作原理圖如圖8所示。主要使Java編寫的應(yīng)用程序和用C、C++編寫的底層驅(qū)動及一些本地鏈接庫能夠?qū)崿F(xiàn)信息的交互。
圖8 JNI原理圖
編譯 JNI 層庫文件的方法如下:
(1)在Android 文件系統(tǒng)下的 packages /apps 下創(chuàng)建一個名為libtel的文件夾, 再在該文件夾中創(chuàng)建 jni 文件夾,在jni文件夾中創(chuàng)建tel.cpp 和Androi d.mk 文件。在tel.cpp文件中,通過JNINativeMethod定義了JNI函數(shù)的映射。通過 registe_android_server_telService(JNIEnv *env)函數(shù)將JNI程序庫與Java類綁定,系統(tǒng)在成功裝載JNI共享庫后會自動調(diào)用JNI_Onload函數(shù),用于初始化JNI模塊。
(2)在packages/apps/ Wiretelephone/jni/ 目錄下運行mmm,生成libtel.so動態(tài)共享庫[8],然后使用cp命令將生成的文件復(fù)制到開發(fā)板對應(yīng)的out/target/product/tq210/rootfs_dir/system/lib目錄下。最后通過adb device命令和adb push命令將tel.tq210.so文件加載到開發(fā)板上,運行以上命令,其編譯成功后,結(jié)果如圖9所示。
圖9 編譯JNI層庫文件
在TQ210開發(fā)板中加載電話撥號程序的APP層程序后,測試驅(qū)動能否正常運行,實現(xiàn)其相關(guān)功能,有如下幾步:
(1)將TQ210開發(fā)板的相關(guān)GPIO接口與示波器相連接,打開開發(fā)板和示波器電源,通過撥號界面撥號時,示波器上出現(xiàn)對應(yīng)的電平波形,即相關(guān)GPIO接口能夠?qū)崿F(xiàn)輸出功能,內(nèi)核驅(qū)動實現(xiàn)了對通用接口的控制。
(2)將TQ210開發(fā)板、MT8880芯片和電話連接起來,在撥號界面進(jìn)行撥號, 經(jīng)測試能順利撥通,即可以控制MT8880芯片產(chǎn)生DTMF信號。
經(jīng)過以上測試,該驅(qū)動程序?qū)崿F(xiàn)了對MT8880芯片的控制,使整個系統(tǒng)在加載了APP程序后能夠?qū)崿F(xiàn)撥號功能,如圖10所示。
通過以上測試,說明該驅(qū)動程序能夠?qū)崿F(xiàn)對MT8880芯片的控制,即Android可以通過新增驅(qū)動模塊識別特定設(shè)備,在加載了應(yīng)用層程序后能夠通過MT8880撥號芯片實現(xiàn)完整的DTMF信號發(fā)送功能。即通過開發(fā)板的通用GPIO口操縱撥號控制芯片,實現(xiàn)語音撥號功能,可以通過在Linux Kernel中添加新的驅(qū)動模塊,使得Android能夠識別添加的特定硬件設(shè)備。在本文基礎(chǔ)上,如果再添加來電顯示的驅(qū)動,控制MT8880的寄存器的設(shè)置,實現(xiàn)來電顯示控制,就可以組成一個完整的電話系統(tǒng)。
[1] 宋小倩,周東升.基于 Android 平臺的應(yīng)用開發(fā)研究[J].軟件導(dǎo)刊,2011,10(2):104-106.
[2] 宋寶華.Linux 設(shè)備驅(qū)動開發(fā)詳解(第2版)[M].北京:人民郵電出版社,2010.
[3] 杜江,周淵平.基于 Android的電話撥號功能[J]. 計算機系統(tǒng)應(yīng)用, 2014(12):245-248.
[4] 姚昱旻,劉衛(wèi)國.Android 的架構(gòu)與應(yīng)用開發(fā)研究[J].計算機系統(tǒng)應(yīng)用,2008,17(11):110-112.
[5] 李寧.Android深度探索(卷1): HAL與驅(qū)動開發(fā)[M].北京:人民郵電出版社,2013.
[6] 付興武,張軍,王洋.基于 SPI 總線協(xié)議的字符設(shè)備驅(qū)動程序[J].計算機系統(tǒng)應(yīng)用,2013(2):146-150.
[7] 李寧.Android開發(fā)權(quán)威指南(第2版)[M].北京:人民郵電出版社,2013.
[8] 明日科技.Android 從入門到精通[M].北京:清華大學(xué)出版社, 2012.
周淵平(1955-), 男, 教授,博士生導(dǎo)師,主要研究方向:通信與信息系統(tǒng)、信號與信息處理。
Design of driver based on Android phone dialing function
Mou Yue, Zhou Yuanping
(College of Electronic Information, Sichuan University, Chengdu 610065, China)
Android is an open operating system based on the Linux Kernel,and it is widely used in a variety of mobile devices.This article combines the Android platform with the dial-up chip MT8880. Android native code supports very few devices,so we need to add a new low-level driver module in Linux Kernel,through the dynamic link libraries which are generated in the HAL layer and JNI layer,so that Android can identify a specific device MT8880,and control the logic output of MT8880.After loading the application,MT8880 chip can send Dual Tone Multi Frequency (DTMF) signal,finally realize Android system dial-up function. After testing,the dial-up driver can control the new device,the phone application can dial successfully.
Android; Linux Kernel; HAL; JNI;MT8880 chip
TP399
A
10.19358/j.issn.1674- 7720.2017.09.026
牟躍,周淵平.基于Android電話撥號功能的驅(qū)動設(shè)計[J].微型機與應(yīng)用,2017,36(9):88-91,99.
2016-12-13)
牟躍(1992-),女, 碩士研究生,主要研究方向:信號與信息處理。