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