基于輸入子系統(tǒng)的Linux觸摸屏驅動的實現(xiàn)
王鑫,孔勇
(上海工程技術大學 電子電氣工程學院,上海201600)
摘要文中對輸入子系統(tǒng)模型進行了介紹并重點對該驅動模型的實現(xiàn)原理及機制進行了分析。在此基礎上,使用輸入子系統(tǒng)驅動模型框架,以ARM處理器S3C2440嵌入式芯片為硬件平臺,配合其芯片內部集成的觸摸屏控制器,設計了Linux下的電阻式觸摸屏驅動程序,實現(xiàn)了在S3C2440平臺上,電阻式觸摸屏的觸點位置坐標采集和觸點跟蹤。
關鍵詞嵌入式;Linux;Linux驅動;觸摸屏;輸入子系統(tǒng)
收稿日期:2015-05-25
基金項目:國家自然科學青年基金資助項目(61305014);上海市自然科學基金資助項目(13ZR1455200)
作者簡介:王鑫(1992—),男,碩士研究生。研究方向:嵌入式系統(tǒng)開發(fā)。E-mail:d_xin_dl@163.com。孔勇(1977—),男,博士。研究方向:光電子技術。
doi:10.16180/j.cnki.issn1007-7820.2015.12.017
中圖分類號TP316.2文獻標識碼A
Realization of Touch Screen’s Driver with Linux Input Subsystem
WANG Xin,KONG Yong
(School of Electronic and Electrical Engineering,Shanghai University of Engineering Science,Shanghai 201600,China)
AbstractIn this article,the principles of Linux input subsystem driver module are introduced and analyzed.The touch screen driver is designed for Linux input subsystem with the ARM embedded processor of SC32440 as hardware platform.And the contact coordinates of the touch screen and contact tracking are realized on the SC32440 hardware platform.
Keywordsembedded;Linux;Linux driver;touch screen;input subsystem
驅動程序,作為底層硬件與上層應用程序之間的橋梁,在Linux系統(tǒng)中具有重要作用。同時為了保證能向應用程序提供統(tǒng)一的接口,在Linux中引入了驅動的分層機制[1]。為同類設備的驅動設計了一個框架,框架中的核心層實現(xiàn)了該設備通用的一些功能,如提供統(tǒng)一的讀、寫接口,而具體的與平臺相關的代碼則被分離出來[2]。輸入子系統(tǒng),就是Linux下對于輸入設備而引入的典型驅動模型。
在文中就Linux中輸入子系統(tǒng)機制進行分析,并使用輸入子系統(tǒng)框架在S3C2440平臺上實現(xiàn)觸摸屏的驅動。
1Linux輸入子系統(tǒng)驅動模型
1.1Linux輸入子系統(tǒng)結構分析
Linux輸入子系統(tǒng)可抽象為輸入子系統(tǒng)核心層、輸入子系統(tǒng)事件處理層和輸入子系統(tǒng)設備驅動層[3]。其中輸入子系統(tǒng)設備驅動層,主要實現(xiàn)對硬件設備的讀寫訪問,中斷設置,并將硬件產生的事件轉換為核心層所定義的規(guī)范提交給事件處理層。對于事件處理層而言,則是用戶編程的接口,處理驅動層提交的數(shù)據(jù)。核心層,為設備驅動層提供了規(guī)范和接口,并將驅動層獲得的硬件數(shù)據(jù)傳遞給事件處理層,其是驅動層和事件處理層之間的“橋梁”。Linux輸入子系統(tǒng)的框架結構如圖1所示。
圖1 Linux輸入子系統(tǒng)的框架結構
1.2Linux輸入子系統(tǒng)實現(xiàn)機制分析
在Linux內核代碼中,輸入子系統(tǒng)核心層的代碼位置為drivers/Input.c,其包含了輸入子系統(tǒng)的接口和所有的宏定義。表示事件處理層的數(shù)據(jù)結構是struct input_handler,每個handler代表一種處理事件的方式。代表設備驅動層的數(shù)據(jù)結構是struct input_dev,其是輸入子系統(tǒng)的設備驅動中最重要的數(shù)據(jù)結構,大部分工作均圍繞其進行,且是驅動的主體。每個input_dev代表一個輸入設備[4]。其分別調用核心層提供的統(tǒng)一接口函數(shù),向核心層注冊自己,然后進行匹配、連接,構成完整的驅動體系。
1.2.1匹配、連接過程分析
在input_handler中,定義有一個id_Table成員,該成員中記錄了該handler所支持的設備信息,如總線類型、產品版本等信息,以及所能處理的事件,如按鍵類事件、絕對位移類事件等。
當input_device或input_handler向核心層注冊時,都會將自己放入一個鏈表中,然后遍歷對方的鏈表,進行匹配。以注冊input_device為例,注冊時,將自己放入鏈表中,然后在handler的鏈表中通過匹配handler中的id_table找到id和事件種類相匹配的handler,執(zhí)行其中指定的連接函數(shù)進行連接,完成兩者的匹配。
1.2.2輸入子系統(tǒng)的事件處理機制
輸入子系統(tǒng)設備層(input_device)中針對具體硬件進行初始化,并獲取底層硬件數(shù)據(jù),如按鍵按下,鼠標滑動等操作所產生的數(shù)據(jù)。通過核心層提供的接口傳遞給事件處理層(input_handler),在此數(shù)據(jù)是以事件的形式由驅動層上報,當事件處理層收到事件后會調用其中的event成員指定的事件處理函數(shù)進行處理,然后通過統(tǒng)一接口提供給應用程序。
事件的上報通過調用input_event()函數(shù)來實現(xiàn),在函數(shù)中傳入事件類型,具體事件等參數(shù)。Linux內核中所支持的事件類型如表1所示。
表1 輸入事件類型表
2觸摸屏原理
觸摸屏從技術原理來區(qū)分,可分為5個基本類型:矢量壓力傳感式觸摸屏、電阻式觸摸屏、電容式觸摸屏、紅外線式觸摸屏、表面聲波式觸摸屏[5],這里用到的是四線式電阻觸摸屏,其結構圖可等效為圖2所示。
圖2 四線式電阻觸摸屏原理等效結構圖
四線觸摸屏包含兩個阻性層,其中一層在屏幕的左右邊緣各有一條垂直總線,另一層在屏幕的底部和頂部各有一條水平總線[6]。
可將四線觸摸屏等效看做一個滑動變阻器,若XP接3.3 V,XM接地,YP和YM不接,當有觸點按下時,檢測YP電壓,此時下面一層相當于電阻,上面一層相當于滑動變阻器指針,觸點越靠近XM,電壓越低,越靠近XP,電壓越高,通過此方法即可得到X坐標,同理可獲取Y坐標。
3觸摸屏驅動程序設計與實現(xiàn)
3.1S3C2440觸摸屏相關寄存器
三星公司ARM處理器S3C2440內部集成了觸摸屏控制器,通過5個寄存器實現(xiàn)對觸摸屏的控制[7],這5個寄存器如表2所示。
表2 S3C2440觸摸屏相關寄存器
S3C2440內部集成的觸摸屏控制器提供分離的X/Y坐標轉換模式、自動的X/Y坐標轉換模式以及等待觸摸按下模式。
3.2設置S3C2440觸摸屏相關寄存器
設置ADCTCS寄存器使其工作于等待按下/抬起模式,在該模式下,當觸摸屏被按下或抬起時會產生中斷(INT_TC),從而實現(xiàn)對觸摸屏狀態(tài)的監(jiān)視。
在中斷中,設置ADCTCS寄存器使其進入X/Y坐標自動轉換模式,啟動A/D轉換??刂破鲿詣愚D換X坐標和Y坐標,并分別將轉換結果寫入ADCDATA0和ADCDATA1寄存器中,隨后產生ADC中斷。在中斷中讀取這兩個寄存器的相應位,則可得到X與Y的坐標[8]。
3.3使用輸入子系統(tǒng)框架實現(xiàn)驅動
輸入子系驅動模型中最重要的就是input_dev結構體,因此首先要做的就是創(chuàng)建一個input_dev結構體,待后續(xù)使用。
3.3.1驅動程序入口函數(shù)設計
驅動程序的入口函數(shù)是由module_init()函數(shù)所指定的[9]。在入口函數(shù)中主要完成以下工作:
(1)使用input_allocate_device()函數(shù) 分配一個input_device結構體。
(2)設置該結構體,設置其能產生的事件。設置能產生案件類事件和絕對位移類事件。
set_bit(EV_KEY,ts->evbit)
set_bit(EV_ABS,ts->evbit)
設置按鍵類事件中的觸摸屏按鍵事件和壓力等級以及設置絕對位移類事件中的X、Y的絕對位移范圍。
set_bit(BTN_TOUCH,ts->keybit);input_set_abs_params(ts,ABS_X,0,0x3FF,0,0);/*設置X絕對位移范圍*/input_set_abs_params(ts,ABS_Y,0,0x3FF,0,0);/*設置Y絕對位移范圍*/input_set_abs_params(ts,ABS_PRESSURE,0,1,0,0);/*設置壓力級別范圍*/
(3)注冊,將分配并設置好的結構體注冊進內核,使用函數(shù)input_register_device(ts)。
(4)硬件相關操作:獲取并使能時鐘
adc_clk=clk_get(NULL,"adc")
clk_enable(adc_clk)
設置S3C2440相關寄存器、注冊中斷[10]。其中寄存器的設置主要設置控制器工作模式為等待按下模式。中斷則需注冊兩個,分別為按下/抬起中斷和ADC轉換完成中斷。
3.3.2驅動程序中斷處理函數(shù)設計
程序中設計了兩個中斷服務程序,分別為處理抬起/按下事件產生的中斷,和處理ADC轉換坐標完成的中斷。
在抬起/按下處理中斷中,首先判斷寄存器ADCDAT0中的第15位,該位為0表示觸摸屏被按下,設置ADCTSC寄存器,使控制器工作于X/Y自動轉換模式。若該位為1,則表示觸摸屏未被按下,設置控制寄存器進入等待按下模式。程序框圖如圖3所示。
圖3 抬起/按下中斷程序框圖
在觸點坐標轉換完成中斷中處理函數(shù)中,讀取ADCDAT0與ADCDAT1,得到X、Y坐標值。將得到X、Y坐標通過輸入子系統(tǒng)的核心層提供的接口上報給事件處理層,代碼如下:
input_report_abs(ts,ABS_X,x_vaule)
input_report_abs(ts,ABS_Y,y_vaule)
input_report_key(ts,BTN_TOUCH,1)
input_report_abs(ts,ABS_PRESSURE,1)
input_sync(xin_ts)
3.3.3驅動程序出口函數(shù)設計
驅動程序的入口函數(shù)是module_exit()函數(shù)所指定的。在出口函數(shù)中主要完成以下操作:(1)使用free_irq()函數(shù)注銷中斷申請。(2)使用 iounmap()函數(shù)注銷申請的虛擬地址映射。(3)使用input_unregister_device()函數(shù)注銷注冊的input_device。(4)使用input_free_device()函數(shù)注銷分配的input_dev結構體。
3.3.4驅動程序的優(yōu)化
通過上述步驟基本實現(xiàn)了觸摸屏的驅動,但為了提高可靠度,還需要對觸摸屏的驅動程序進行優(yōu)化,使其能更準確地得到X、Y坐標。可使用的優(yōu)化方法有很多,如設置ADCDLY寄存器進行延時讀取、多次測量X、Y坐標取平均值、軟件過濾等。
文中使用平均值優(yōu)化法,在按下抬起中斷中進行優(yōu)化。圖4所示為平均值優(yōu)化方式的程序框圖。
圖4 使用平均值優(yōu)化X、Y坐標程序框圖
4驅動程序測試
4.1使用Tslib程序測試驅動
Tslib是一個開源程序,能夠為觸摸屏驅動獲得的采樣提供諸如濾波、去抖、校準等功能,通常作為觸摸屏驅動的適配層,使用輸入子系統(tǒng)提供的接口將觸摸屏數(shù)據(jù)進行處理,為上層的應用提供了一個統(tǒng)一的接口。這里用其測試驅動程序。
將Tslib源代碼進行編譯、安裝,然后放到目標板的文件系統(tǒng)中,修改/etc/ts.conf 文件。并添加環(huán)境變量,使其能夠在文件系統(tǒng)中使用,系統(tǒng)中輸入指令如下:
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
完成上述步驟后,加載編譯好的觸摸屏驅動以及LCD顯示驅動,即可使用tslib程序驗證觸摸屏驅動。運行ts_test程序,在觸摸屏上滑動則可看到光標隨著筆桿移動,實現(xiàn)觸點跟蹤,效果如圖5所示。
圖5 觸摸屏觸點跟蹤效果圖
4.2采集觸摸屏觸點坐標
在驅動程序中,使用printk()函數(shù),將得到的X、Y坐標輸出,打印在控制臺上。手指在觸摸屏上滑動,在主機上通過串口終端能實時顯示觸點坐標,效果如圖6所示。
圖6 X、Y坐標采集效果圖
5結束語
對Linux下輸入子系統(tǒng)驅動模型的主要機制進行分析,并介紹了四線式觸摸屏的工作原理?;谳斎胱酉到y(tǒng)驅動模型框架,在以ARM為內核的S3C2440平臺上實現(xiàn)了觸摸屏驅動。編譯、安裝,設置tslib程序,在目標平臺上進行測試,驗證驅動功能,實現(xiàn)觸點采集及觸點跟蹤。
參考文獻
[1]陳濤.嵌入式Linux下的LCD驅動程序設計與實現(xiàn)[J].電子科技,2010,23(11):22-24.
[2]宋寶華.Linux設備驅動開發(fā)詳解[M].2版.北京:人民郵電出版社,2010.
[3]羅勇剛,夏定純.電阻式觸摸屏的校準與應用研究[J].武漢科技學院學報,2007,20(12):47-49.
[4]王闖.Linu中Input輸入子系統(tǒng)分析[J].電腦開發(fā)與應用,2012,25(7):70-71.
[5]史悅.觸摸屏技術及應用[M].成都:電子科技大學出版社,2002.
[6]蔡紅娟.電阻式觸摸屏校準算法的優(yōu)化[J].制造業(yè)自動化,2012,34(7):21-23.
[7]Samsung Electronics.S3C2440A32-Bit CMOS microcontroller user’s manual[M].Korea:Samsung Electronics,2004.
[8]韋東山.嵌入式Linux應用開發(fā)完全手冊[M].北京:人民郵電出版社,2008.
[9]Jonatban C,Alessandro R,Greg K H.Linux 設備驅動程序[M].3版.魏永明,譯.北京:中國電力出版社,2005.
[10]劉少平.基于 Linux內核輸入子系統(tǒng)的驅動研究[J].電子設計工程,2012,20(17):29-31.