楊斌斌 張雪英 王玉宏
摘 要:主要介紹基于嵌入式Linux的矩陣鍵盤驅動程序設計的方法,硬件平臺基于TI提供的OMAP5912構建的嵌入式語音識別系統,充分利用OMAP5912的外圍硬件資源,矩陣鍵盤作為平臺設備和輸入設備,利用Linux內核提供的輸入子系統。輸入子系統為輸入設備驅動開發提供了良好的接口,提高了驅動程序的開發效率。驅動開發完成后,在MiniGui和Qtopia下測試,結果證明驅動程序工作高效、穩定。
關鍵詞:矩陣鍵盤;嵌入式Linux;OMAP5912;設備驅動
中圖分類號:TP334.2文獻標識碼:B
文章編號:1004 373X(2009)02 039 03
Research and Development of Matrix Keyboard Device Driver Based on Embedded Linux
YANG Binbin,ZHANG Xueying,WANG Yuhong
(College of Information Engineering,Taiyuan University of Technology,Taiyuan,030024,China)
Abstract:This paper mainly introduces a scheme of matrix keyboard device driver based on embedded Linux.The hardware platform is the embedded speech recognition system based on OMAP5912.Taking full advantage of the peripheral equipments of OMAP5912,the matrix keyboard is treated as platform device and input device.The Linux kernel offers input subsystem which provides interface to the developer and improves efficiency of the driver development.After the development of device driver is achieved,it is tested via MiniGui and Qtopia and the result proves that the device driver is effective and stable.
Keywords:matrix keyboard;embedded Linux;OMAP5912;device driver
0 引 言
隨著以計算機技術、通信技術和軟件技術為核心的信息技術的發展,嵌入式系統在各個行業中得到了廣泛的應用。嵌入式系統已成為當今IT行業的焦點之一。而在嵌入式系統中,鍵盤是重要的人機交互設備之一。嵌入式Linux是一種開放源碼、軟實時、多任務的操作系統,是開發嵌入式產品的優秀操作系統平臺,是在標準Linux基礎上針對嵌入式系統進行優化和裁剪后形成的,因此具有Linux的基本性質。在此提出的矩陣鍵盤驅動程序的設計方案是以嵌入式Linux和TI OMAP5912處理器為軟硬件平臺的,在設計的嵌入式語音識別應用平臺中,通過測試,表明其具有良好的穩定性和實時性。
1 硬件原理
OMAP5912處理器是由TI應用最為廣泛的TMS320C55X DSP內核與低功耗、增強型ARM926EJ-S微處理器組成的雙核應用處理器[1]。用這樣一種組合方式將2個處理器整合在1個芯片后,開發人員可以根據實際情況,利用 DSP 運行復雜度較高的數字信號處理任務,利用 ARM 運行通信、控制和人機接口方面的任務,從而使便攜式設備在保持良好人機交互環境的基礎上,有效地降低功耗[2]。在外設方面,OMAP5912微處理器支持常用的各種接口,其中通過MPUIO接口最多可支持8×8的矩陣鍵盤,系統中采用這個接口擴展了一個4×5的矩陣鍵盤[3]。其硬件連接示意圖如圖1所示,其中按鍵行陣列必須提供上拉信號,列陣列加二極管,防止瞬間電流過大對MPUIO口造成沖擊。
按照鍵盤的構造方式人們把鍵盤劃分為線性鍵盤和矩陣鍵盤[4]。其中,線性鍵盤是指每個按鍵都占用嵌入式處理器的1個I/O端口,并通過這個I/O端口實現人機交互,各個按鍵之間互不影響。使用這種方案的優點是簡單、可靠,但是線性鍵盤對I/O端口的占用量很大。因此,嵌入式系統中很少采用這種方法。
另外一種矩陣鍵盤是指當按鍵數量過多時,采用矩陣的排列方法,將按鍵設計成n行m列的矩陣形式。其中,每個按鍵占用行和列的1個交叉點,并且以行和列為單位引出信號線。這樣只需要占用n+m個I/O端口,卻可以驅動n×m個按鍵,大大節省了對嵌入式處理器I/O端口的占用,節省了寶貴的資源。矩陣鍵盤在減少嵌入式處理器I/O端口占用的問題上做出了很大的貢獻,但隨之而來的問題是如何確定矩陣中按鍵的位置,這里采用列掃描法,其思路如下:
在鍵盤初始化階段,所有的列信號(KBC)都被設置輸出為低電平。如果矩陣鍵盤中的1個按鍵按下,則相應的行信號和列信號線短路,行信號線(KBR)輸入由高電平變為低電平,產生1個中斷,然后在驅動的中斷服務程序中按照表1中的序列逐列掃描列信號,讀取行信號的狀態,根據讀回來的行信號狀態就可以判斷有那些按鍵按下[3]。
另外,鍵盤驅動必須解決的一個問題是鍵盤的抖動[4]。在按鍵按下和抬起的過程中,電壓信號會出現很多毛刺,這主要是由于機械按鍵的彈性作用引起的。盡管觸點看起來非常穩定,而且快速地閉合,但相對于嵌入式處理器的運行速度來說,這種動作是比較慢的。這種脈沖在某些按鍵功能設計時,如果處理不當可能會帶來災難性的后果。所以必須對按鍵信號進行防抖檢測。
按鍵防抖檢測的核心思想是在嵌入式處理器的幾個時鐘周期內,通過對按鍵信號進行多次訪問,查看電平狀態是否保存一致[5]。如果保持一致,則說明按鍵狀態已經穩定;否則,說明之前檢測到的按鍵信號是抖動信號或外界信號干擾,系統將不會對其進行任何處理。
2 嵌入式Linux設備驅動程序
在Linux內核源代碼中,各種驅動程序的代碼量占據了整個Linux代碼的85%[6]??梢?, Linux設備驅動在整個操作系統中起著舉足輕重的作用。設備驅動是操作系統內核和機器硬件之間的接口,它們控制著設備的操作動作,并且提供了一組API接口給應用程序,使得應用程序能夠與這個設備互動[7]。而且,設備驅動為應用程序屏蔽了硬件的細節,在應用程序看來,硬件設備只是1個設備文件,應用程序就可以像操作普通文件一樣對硬件設備進行操作[8]。在Linux操作系統中,通常將外圍設備分為3種類型:字符設備、塊設備和網絡設備[6]。
而在Linux操作系統中,還有一類設備被定義為“平臺設備”,通常SoC(System on Chip)系統中集成的獨立的外設單元都被當作平臺設備來處理,這里把4×5的矩陣鍵盤也定義為平臺設備。所謂的“平臺設備”并不是與字符設備、塊設備和網絡設備并列的概念,而是Linux系統提供的一種附加手段,例如,鍵盤驅動,它本身是字符設備,但也將其歸納為平臺設備。
另外,鍵盤又屬于輸入設備,Linux內核提供了輸入子系統,如鍵盤、觸摸屏、鼠標等輸入設備都可以利用輸入子系統的接口函數來實現設備驅動[4]。輸入子系統由核心層(Input Core)、驅動層和事件處理層(Event Handler)三部分組成[9]。在Linux內核中,使用輸入子系統實現輸入設備驅動的時候,驅動的核心工作是向系統報告按鍵、觸摸屏、鼠標等輸入事件,而不再需要關心文件操作接口,因為輸入子系統已經完成了文件操作接口。通過輸入子系統,實現輸入設備驅動時只需要完成以下工作:
(1)在模塊加載函數中告知輸入子系統輸入設備可以報告的事件。例如,可通過__set_bit(EV_KEY,input_dev->evbit)來告知輸入子系統該設備可報告按鍵事件。
(2)在模塊加載函數中注冊輸入設備。注冊函數為:int input_register_device(struct input_dev *dev);
(3)當有輸入事件發生時,如按鍵按下/抬起、觸摸屏被觸摸/抬起/移動時,通過input_report_xxx()報告發生的事件及對應的鍵值、坐標等狀態。主要的事件類型包括EV_KEY(按鍵事件)、EV_REL(相對值,如鼠標移動,報告相對于最后一次位置的偏移)和EV_ABS(絕對值,如觸摸屏)。用于報告EV_KEY事件的函數為:void input_report_key(struct input_dev *dev,unsigned int code,int value);
(4)在模塊卸載函數中注銷輸入設備。注銷輸入設備的函數為:void input_unregister_device(struct input_dev *dev);
3 矩陣鍵盤驅動中的數據結構
首先,定義一個整型數組osk_keymap[]用來定義按鍵映射表,把20個按鍵返回的碼值映射成內核中標準的鍵碼,這樣有利于與上層應用程序的交互。通過KEY(col,row,code)宏定義來實現映射關系,如要把第2行第4列的按鍵映射為回車鍵,則通過KEY(3,1,KEY_ENTER)便可實現。其中KEY_ENTER是內核中定義的標準的鍵碼。
其次,定義矩陣鍵盤的設備結構體omap_kp,其定義如下:
struct omap_kp {
struct input_dev *input; //定義輸入設備結構體指針
struct timer_list timer; //定義計時器
int irq; //中斷號
unsigned int rows; //行數
unsigned int cols; //列數
unsigned long delay; //延時
unsigned int debounce; //去抖的間隔時間
int suspended; //判斷設備是不是懸停
spinlock_t suspend_lock; //自旋鎖
};
4 矩陣鍵盤驅動程序設計及測試
首先,實現矩陣鍵盤驅動的加載和卸載函數,分別通過調用platform_driver_register()和platform_driver_unregister()實現矩陣鍵盤作為一個平臺設備的注冊和注銷。
其次,實現矩陣鍵盤驅動的探測和移除函數。在探測函數中,初始化行數、列數、中斷號以及按鍵映射表。然后分配內存空間和輸入設備,初始化omap_kp這個設備結構體和輸入設備結構體input_dev,初始化定時器,設置輸入設備可以報告的事件類型,并注冊輸入設備。最后申請中斷,申請中斷成功后,使能中斷。移除函數則完成相反的工作。
最后,實現矩陣鍵盤驅動的核心部分,也就是中斷部分。眾所周知,在Linux的中斷處理中分為2部分,分別是頂半部(top half)和底半部(bottom half)[10]。
頂半部完成盡可能少的比較緊急的功能,它只是簡單地讀取寄存器中的中斷狀態并清除中斷標志后就進行“登記中斷”的工作?!暗怯浿袛唷币馕吨鴮⒌装氩刻幚沓绦驋斓皆撛O備的底半部執行隊列中去。這樣,頂半部執行的速度就會很快,可以服務更多的中斷請求。
底半部,是實現中斷處理的真正部分,它來完成一些延緩的耗時任務,首先通過列掃描法檢測各個按鍵狀態有沒有變化,若有變化再判斷是哪一列哪一行發生變化,按鍵的行和列確定以后,通過鍵值映射表來查找其有沒有對應的鍵值;若有則通過input_report_key()向內核報告按鍵的鍵值;否則,對應的按鍵沒有定義鍵值,向內核報告為假按鍵(Spurious Key)。然后,延時(1/20)Hz再判斷按鍵是否抬起。
驅動開發完成后,以模塊方式加入到內核,并在MiniGui和Qtopia下進行了測試,在Qtopia下測試結果如圖2所示,證明矩陣鍵盤驅動工作正常、有效。
5 結 語
在此介紹了基于OMAP5912和嵌入式Linux的一種矩陣鍵盤驅動的工作原理和開發方案。該驅動以靜態方式加入內核后,通過測試證明矩陣鍵盤驅動工作穩定、高效,在MiniGui和Qtopia的記事本中,都能正確顯示正確的鍵值,基本上實現了其功能,并成功地應用于所開發的嵌入式語音識別系統中。
參考文獻
[1]OMAP5912 Applications Processor Data Manual[S].2004.
[2]韓金燕,盧素鋒,王勝坤.一種基于TI OMAP的PDA的設計[J].電腦開發與應用,2007,20(2):47-49.
[3]OMAP5912 Multimedia Processor Keyboard InterfaceReference Guide[S].2004.
[4]宋寶華.Linux設備驅動開發詳解[M].北京:人民郵電出版社,2008.
[5]李杰,曹宇,朱堅,等.基于嵌入式Linux的矩陣鍵盤設計與實現[J].現代電子技術,2006,24(3):81-83.[6]孫天澤.嵌入式設計及Linux驅動開發指南基于ARM9處理器[M].北京:電子工業出版社,2007.
[7]祝世海.嵌入式微處理器的Linux設備驅動程序開發[J].哈爾濱商業大學學報:自然科學版,2007,23(3):329-331.
[8]李世勇,肖竟華.基于Linux驅動程序的編寫技術[J].電腦與信息技術,2006,14(3):43-45.
[9]Alessandro Rubini,Jonathan Corbet,Gerg Kroah-Hartman.Linux Device Drivers.Third Edition.O′Reilly,2008.
[10]王兵,王冰峰.嵌入式Linux按鍵驅動程序的設計[J].科技資訊,2007(1):220-223.
作者簡介 楊斌斌 男,1983年出生,山西新絳人,在讀碩士研究生。研究方向為語音信號處理與嵌入式系統。
張雪英 女,太原理工大學教授、博士生導師。研究方向為語音信號處理。