梁 坤
(深圳市遠望谷信息技術(shù)股份有限公司,廣東 深圳 518057)
Android系統(tǒng)是一種基于Linux內(nèi)核的開放源碼的操作系統(tǒng),目前主要應(yīng)用于移動設(shè)備中(如智能手機、平板電腦等)。而在工業(yè)控制領(lǐng)域的終端設(shè)備中,則主要采用Windows CE和嵌入式Linux系統(tǒng)。Android系統(tǒng)的開源特性和良好的UI系統(tǒng),相比Windows CE和Linux系統(tǒng)具有一定的優(yōu)勢,并有逐漸向工業(yè)控制的終端設(shè)備滲透的趨勢。
鍵盤模塊作為一種人機交互接口,在各種終端設(shè)備中得到了廣泛應(yīng)用。矩陣式鍵盤[1-7]占用較少的I/O,能提供較多的按鍵,是鍵盤設(shè)計中常見的一種低成本設(shè)計方案。隨著工控領(lǐng)域終端設(shè)備的智能化,各主控芯片集成的功能越來越多,GPIO往往與其他功能引腳復(fù)用。為了最大限度地利用主控芯片資源,GPIO資源在硬件設(shè)計時須謹慎規(guī)劃。雖然Android系統(tǒng)自帶虛擬鍵盤,但屏幕的大小和觸屏靈敏度直接影響虛擬鍵盤的使用效率和用戶體驗,一旦觸摸屏失靈,虛擬鍵盤將不能使用。因此在可靠性和成本要求甚高的工業(yè)控制領(lǐng)域并不是最佳選擇。
本文采用I2C接口的TCA9535[8]芯片實現(xiàn)了一種通用的矩陣式鍵盤模塊,并完成了該模塊在Android系統(tǒng)上的驅(qū)動開發(fā)。由于采用的是I2C總線方式,其他設(shè)備也可掛載到同一總線上,因此最大限度地利用了主控芯片的資源。
鍵盤模塊通過TCA9535芯片擴展I/O實現(xiàn)。TCA9535芯片是TI公司生產(chǎn)的一款I(lǐng)2C接口擴展I/O的芯片,芯片供電范圍為1.65 V~5.5 V,最大支持 400 kHz的通信速率,最大待機電流為 3μA;具有16個獨立I/O和一個開漏極低電平輸出的中斷口,所有I/O口具備機型反轉(zhuǎn)功能,能直接驅(qū)動LED;具有3根地址線,可根據(jù)應(yīng)用系統(tǒng)要求設(shè)置芯片的地址。芯片內(nèi)部有8個可編程的寄存器,分別是2個輸入端口寄存器、2個輸出端口寄存器、2個極性翻轉(zhuǎn)寄存器和2個端口配置寄存器。
鍵盤模塊采用5×5矩陣式按鍵設(shè)計,鍵盤背光通過一個I/O口控制一個MOSFET管驅(qū)動多個并聯(lián)的LED實現(xiàn),總共使用TCA9535芯片的11個I/O口。鍵盤模塊與主控芯片AM3730之間通過I2C接口和一根中斷線連接,如圖1所示。
圖1 鍵盤模塊示意圖
當按鍵陣列有按鍵按下時,TCA9535芯片產(chǎn)生一個低電平中斷。主控芯片檢測到中斷信號后,通過I2C總線配置TCA9535芯片的相關(guān)寄存器,對鍵盤陣列I/O進行掃描。每一次掃描后,讀取鍵盤陣列I/O值。多次掃描后,完成按鍵位置的確定,并根據(jù)位置確定鍵值。主控芯片確認有按鍵按下時,通過I2C總線控制TCA9535芯片控制背光的I/O口,點亮鍵盤的背光。在按鍵過后一段時間內(nèi),若沒有新的按鍵產(chǎn)生,則主控芯片將關(guān)閉鍵盤背光。
Android系統(tǒng)大體可分為4層[9],從下往上依次是:Linux內(nèi)核層、Libraries層、Framework層和 Application層。Android系統(tǒng)與硬件相關(guān)的驅(qū)動基本在Linux內(nèi)核層。因此,本文涉及的TCA9535設(shè)備驅(qū)動是指Linux內(nèi)核層的設(shè)備驅(qū)動。本文Android系統(tǒng)為Android ICS 4.0.3,其中的Linux內(nèi)核版本為2.6.37。
Linux內(nèi)核 I2C設(shè)備驅(qū)動包含 3層[10],分別是:I2C總線驅(qū)動(I2C core)、I2C 控制器驅(qū)動(I2C adapter)及 I2C 設(shè)備的驅(qū)動(I2C driver)。I2C總線驅(qū)動主要實現(xiàn)對I2C總線及控制器和設(shè)備驅(qū)動的管理。這部分代碼為通用部分,Linux內(nèi)核已經(jīng)完善,不需要改動。I2C控制器驅(qū)動跟硬件相關(guān),主要是構(gòu)造一個與I2C總線層接口的數(shù)據(jù)結(jié)構(gòu),并通過接口函數(shù)向I2C總線注冊一個控制器。同時,實現(xiàn)對I2C控制器中斷的處理函數(shù),完成I2C設(shè)備具體功能的實現(xiàn)。I2C設(shè)備驅(qū)動主要是構(gòu)造一個與I2C總線層接口的數(shù)據(jù)結(jié)構(gòu),通過接口函數(shù)向I2C總線層注冊一個I2C設(shè)備驅(qū)動。同時構(gòu)造一個與用戶層接口的數(shù)據(jù)結(jié)構(gòu),通過接口函數(shù)向內(nèi)核注冊一個字符型設(shè)備。本文涉及的驅(qū)動開發(fā)主要包含I2C控制器驅(qū)動和I2C設(shè)備驅(qū)動。
(1)驅(qū)動文件添加
在Linux內(nèi)核的drivers/i2c/muxes目錄下,新建一個tca9535kbd.c文件(該文件為TCA9535的設(shè)備驅(qū)動文件),同時在該層的Makefile和Kconfig文件中,添加對新建文件的支持。重新編譯內(nèi)核后,須選中添加的部分。如Makefile中添加:obj-$(CONFIG_I2C_MUX_TCA9535)+=tca9535kbd.o
(2)構(gòu)建與I2C總線層接口的數(shù)據(jù)結(jié)構(gòu)和接口函數(shù)
(3)鍵值處理
主控芯片接收到中斷信號后,進入中斷服務(wù)函數(shù)(tca9535kbd_keys_isr函數(shù))進行按鍵事件處理。由于鍵盤按鍵的處理(鍵值掃描及去抖等)需要一定的時間,為了不長時間占用CPU資源,中斷服務(wù)程序只負責將真正的按鍵事件處理函數(shù)(tca9535kbd_do_work函數(shù))放在內(nèi)核的后臺任務(wù)隊列。內(nèi)核將根據(jù)規(guī)則進行自動調(diào)度并執(zhí)行。向內(nèi)核隊列中加入按鍵事件處理函數(shù)通過INIT_WORK函數(shù)和schedule_work函數(shù)來實現(xiàn)。初始化工作隊列函數(shù)(INIT_WORK函數(shù))在接口函數(shù)tca9535kbd_attach_adapter中調(diào)用,任務(wù)加入內(nèi)核后臺隊列(schedule_work函數(shù))在中斷服務(wù)程序中調(diào)用。
按鍵事件處理流程如圖2所示。
圖2 按鍵事件處理流程圖
圖2中,鍵盤的防抖采取時間過濾、多次讀取來確定。向系統(tǒng)上報按鍵事件包括按鍵按下事件和按鍵松開事件。由于TCA9535芯片只有在有按鍵按下時才產(chǎn)生中斷,按鍵處理程序中的150 ms的較大延時(經(jīng)驗值)用于防止一次按鍵事件被處理成多次按鍵事件(不影響鍵連擊和長按事件的處理)。另外,在上報按鍵事件時,須同時上報按鍵按下和按鍵松開事件,而不額外檢測按鍵松開。具體實現(xiàn)函數(shù)如下:
(1)構(gòu)建I2C總線驅(qū)動數(shù)據(jù)結(jié)構(gòu)
(2)注冊設(shè)備驅(qū)動
(3)硬件平臺設(shè)備初始化
在主控芯片對應(yīng)的平臺文件中須添加對設(shè)備的初始化參數(shù),并向平臺注冊硬件設(shè)備(本文所對應(yīng)的平臺文件為內(nèi)核中arm/arm/mach-omap2/board-omap3beagle.c)。
Andorid系統(tǒng)的鍵盤按鍵事件由WindowManagerService服務(wù)來管理,然后以消息的形式轉(zhuǎn)發(fā)給當前活動的應(yīng)用程序進行處理。Linux內(nèi)核層上報按鍵事件時附帶了一個鍵值(在Linux內(nèi)核include/input.h文件中定義),該鍵值與Andorid系統(tǒng)使用中的鍵值對應(yīng)時才能正確顯示按鍵值。Andorid系統(tǒng)通過qwerty.kl和generic.kl文件進行鍵值的映射。一些常用的按鍵在Linux內(nèi)核層和Android層基本一致。若需要自定義按鍵,或者內(nèi)核與Andorid系統(tǒng)層個別鍵值不一致時,須修改一方的值以完成兩者的統(tǒng)一。
本文介紹了一款A(yù)ndroid系統(tǒng)矩陣式鍵盤的設(shè)計與實現(xiàn)方式,實際使用證明該鍵盤模塊工作穩(wěn)定,達到了預(yù)期設(shè)計目標。該方案基于I2C總線,有利于提高主控芯片的資源利用率,方便移植到其他嵌入式系統(tǒng)上,具備很好的可擴展性。文中介紹的驅(qū)動開發(fā)流程對Android系統(tǒng)的底層開發(fā)具有一定的參考價值和借鑒意義。
[1]王選民.智能儀器原理及設(shè)計[M].北京:清華大學出版社,2008.
[2]黃菁,劉青春.ARM嵌入式系統(tǒng)GPIO擴展鍵盤設(shè)計[J].自動化應(yīng)用,2011(7):1-2.
[3]孟桂芳.基于嵌入式Linux的矩陣鍵盤設(shè)備驅(qū)動的設(shè)計[J].蘇州大學學報(工科版),2011,31(4):71-74.
[4]李其珂,付紅橋.基于嵌入式Linux的矩陣鍵盤驅(qū)動研究與實現(xiàn)[J].重慶理工大學學報(自然科學),2012,26(12):88-92.
[5]傅超,張昌華,孟勁松.基于嵌入式Linux的矩陣鍵盤模塊的設(shè)計[J].微型機與應(yīng)用,2012,31(21):7-10.
[6]徐德龍,余瑾.基于嵌入式Linux系統(tǒng)的鍵盤驅(qū)動設(shè)計[J].單片機與嵌入式系統(tǒng)應(yīng)用,2013(2):21-23.
[7]張永強,鄧少芝,王凱,等.專用鍵盤接口芯片的一種CPLD實現(xiàn)方案[J].電子技術(shù)應(yīng)用,2002,28(11):17-18.
[8]TI.TCA9535 datasheet[EB/OL].(2009)[2009].http://www.ti.com/product/tca9535.
[9]鄧平凡.深入理解 Android:卷 I[M].北京:機械工業(yè)出版社,2011.
[10]杜博,方向忠.嵌入式 Linux系統(tǒng)下 I2C設(shè)備驅(qū)動程序的開發(fā)[J].微計算機信息,2006,22(4-2):31-33.