本文介紹了當前比較流行的開放源代碼的嵌入式操作系統μClinux下驅動程序的一般結構,以及觸摸屏控制器和Motorola DragonBallMCVZ328 CPU的連接。在此基礎上,詳細講述了觸摸屏驅動程序設計的一些關鍵技術,如阻塞型I/O操作、任務隊列以及系統定時器的應用等,解決了采樣數量控制問題,具有較好的移植性。
背景介紹
隨著信息技術的發展,嵌入式系統越來越廣泛地應用到航空航天、通訊設備、工業控制等領域。由于尺寸的限制,觸摸屏代替鍵盤和鼠標成為嵌入式系統首選的輸入工具。同時嵌入式系統也逐漸摒棄了傳統的循環控制模式,而是引入操作系統完成進程間切換和任務調度。μClinux就是一種優秀的開放源代碼的嵌入式操作系統。它經過各方面的小型化改造,形成了一個高度優化的、代碼緊湊的嵌入式Linux,雖然它的體積很小,μClinux仍然保留了Linux的大多數優點:穩定良好的移植性、優秀的網絡功能、完備的對各種文件系統的支持以及標準豐富的API。比較起其它幾種應用較多的嵌入式操作系統,像vxworks、winCE等,它較為低廉的價格以及方便的用戶程序開發,無疑是其巨大的優勢。用戶可以方便地從互聯網上找到最新內核版本、編譯器以及其它必需的軟件環境,這也促使眾多愛好者加盟。
研究現狀
由于觸摸屏使用得越來越廣泛,所以相應的研究與工程實踐比較多。在現有的工作中,已有很多工程師對觸摸屏控制器ADS7846與StrongARM平臺的硬件連接以及在WinCE操作系統中軟件驅動程序開發進行了研究,并對改進觸摸屏控制器硬件精度上做了一定探索。而本文的主要貢獻在于詳細描述了在μClinux這一嵌入式操作系統中觸摸屏驅動程序硬件及軟件設計。實踐證明,這一設計具有比較高的精度、穩定性和開放性,而且跨平臺性也較好,因此必將給嵌入式設備提供更多選擇。
硬件設計
本設計中硬件平臺微處理器選用Motorola公司的MC68VZ328,它是一款M68k體系的32位低功耗微處理器,采用SoC技術設計,具有典型的嵌入式微處理器的特征;觸摸屏選用TI(原為Burr-Brown公司的產品,由于該公司已被TI公司收購,所以下文均用TI公司)公司的ADS7843。在本設計中,CPU與觸摸屏以主從方式工作,觸摸屏工作于從設備(slave)狀態。本設計中硬件電路不同于傳統設計,而是充分利用了ADS7843中的BUSY信號線,如圖1所示。
ADS7843是一款四線電阻式觸摸屏控制芯片,它主要完成兩件事情:其一,是完成電極電壓的切換;其二,是采集接觸點處的電壓值。它由兩層透明的阻性導體層組成,在導體層中間充滿了用粘性絕緣液體材料做成的隔離層和由導電性能極好的材料構成的電極。
觸摸屏工作時,上下導體層相當于電阻網絡,如圖2所示。當某一層電極加上電壓時,會在該網絡上形成電壓梯度。若有外力使得上下兩層在某一點接觸,則在電極未加電壓的另一層可以測得接觸點處的電壓,從而知道接觸點處的坐標。比如,若在頂層的電極(X+、X-)上加上電壓,則在頂層導體層上形成電壓梯度;當有外力使得上下兩層在某一點接觸,在底層就可以測得接觸點處的電壓,再根據該電壓與電極(X+)之間的距離關系,知道該處的X坐標。然后,將電壓切換到底層電極(Y+、Y-)上,并在頂層測量接觸點處的電壓,從而知道Y坐標。對電壓在橫向和縱向導體層之間的切換以及A/D轉換,需要先通過串行外設接口(SPI)往ADS7843發送控制字,轉換完成后再通過SPI讀出電壓轉換值。
軟件設計
μClinux下驅動程序的特點
μClinux繼承了Linux的設備管理方法,將所有的設備看做具體的文件,通過文件系統層對設備進行訪問。所以在Clinux的框架結構中,和設備相關的處理可以分為兩個層次——文件系統層和設備驅動層。設備驅動層屏蔽具體設備的細節,文件系統層則向用戶提供一組統一的規范的用戶接口。這種設備管理方法可以很好地做到“與設備無關性”,使Clinux可以根據硬件外設的發展進行方便的擴展,比如要實現一個設備驅動程序,只要根據具體的硬件特性向文件系統提供一組訪問接口即可。
μClinux中的設備可以分為3類:字符設備、塊設備和網絡設備。其中字符設備沒有緩沖區,數據的處理是以字節為單位按順序進行的,它不支持隨機讀寫,觸摸屏即屬于字符設備的一種。
驅動程序在內核中裝載的方式有兩種:一種是直接編譯進內核,在系統初始化的時候就對設備進行注冊;一種是模塊化加載的方法,將驅動程序編譯成目標文件(*.o),需要添加設備時,使用insmod命令向系統注冊,停止使用時,用rmmod命令卸載。對于觸摸屏這種基本的輸入工具,建議采取直接編譯進內核的方式,這樣系統一啟動就可以使用了。
向內核注冊一個字符設備的函數為:externintregister_chrdev(unsignedintmajor,constchar*name, structfile_operations*fops);內核用主設備號和次設備號惟一地標識一個設備。參數major對應所請求的主設備號,name對應設備的名字,fops是一個指向file_operations結構的指針,它是Clinux下編寫驅動程序用到的一個關鍵的數據結構,它提供了應用空間與驅動程序的調用接口。這個數據結構的每一項都指向驅動程序完成的一個功能。
在2.4版本內核中對該結構采取標記結構初始化語法(TaggedStructureInitializationSyntax),與2.0內核比較,這種語法可移植性更好,程序的可讀性和代碼的緊湊性都比較好。以觸摸屏為例:
staticstruct file_operations ts_fops={
owner:THIS_MODULE,
read:ts_read, //讀數據操作
poll:ts_poll, //非阻塞操作
ioctl:ts_ioctl, //I/O控制操作
open:ts_open, //打開設備
release:ts_release, //釋放設備
fasync:ts_fasync, //異步觸發}
完整的結構還包括llseek、readdir等函數指針,只是由于在本程序中沒有用到,所以省略不寫,內核把它們默認為空(NULL)。
觸摸屏驅動程序的流程及關鍵函數
在本設計中,我們使用μClinux2.4內核。驅動程序主要設計思想是:驅動程序在初始化結束后,進入空閑狀態,等待中斷的到來。一旦筆中斷(pen_irq)發生,則進入中斷處理程序,進行數據采樣、轉換和傳輸,同時,程序對各種不同的情況進行鑒別和異常處理。
觸摸屏軟件流程如圖3所示。在驅動程序中設定了觸摸屏所處的7個不同狀態,分別用從-1到5的數字表征,這7個狀態構成了一個觸摸屏狀態機,系統根據當前狀態做出下一步的處理,如表1所示。整個軟件設計根據功能可以劃分為5個部分,分別是初始化、設備打開、讀操作、中斷處理以及I/O控制,下面具體介紹每一部分。
驅動程序初始化
在mc68328digi_init()中向內核注冊設備驅動函數:err=misc_register(&mc68328_digi),在init_ts_settings()中設定觸摸屏的當前參數:內核版本號、筆移動判別閾值、采樣時間、消除抖動開關、消除抖動時間等參數,這些均由用戶根據自己的液晶屏以及精度要求來定制,也可以在應用程序中用I/O控制函數ioctl()來設定,本文將在參數分析中具體分析這些參數的意義。
打開設備
在ts_open()函數中,驅動程序向內核注冊中斷。中斷也可以在系統初始化的時候向內核注冊,但是一般不建議這樣做,因為在加載的設備比較多時,這樣做有可能造成中斷的沖突。打開一個設備,才讓該設備占用中斷,是一個較好的策略。向內核注冊中斷處理程序主要實現兩個功能,一是注冊中斷號,二是注冊中斷處理函數。
本程序中,向內核注冊了兩個中斷處理程序,分別是:
request_irq(PEN_IRQ_NUM, handle_pen_irq,IRQ_FLG_STD,
“touch_screen”,NULL)和request_ irq(SPI_IRQ_NUM,handle_spi_irq, IRQ_FLG_STD,“spi_irq”,NULL);
在前者中,PEN_IRQ_NUM是中斷號,可以指定,也可以動態分配。在該驅動程序中,指定筆中斷分配中斷號為19;handle_pen_irq是中斷處理函數,IRQ_FLG_STD是申請時的選項,它決定中斷處理程序的一些特性,這里表示由系統內部占用;touch_ screen是設備名。在后者中,程序向內核注冊SPI中斷,用來在CPU和外設間傳遞數據,分配的中斷號是0,handle_spi_irq是SPI中斷處理函數。
此外,在觸摸屏驅動初始化子函數init_ts_drv()中,進行了如下工作:
(1)觸摸屏狀態的初始化;
(2)筆信息(pen_values)的初始化;
(3)初始化定時器并設置超時函數handle_timeout();
(4)初始化寄存器。初始化等待隊列,等待隊列是由等待觸摸事件發生的進程組成的一個隊列,它包括頭尾指針和一個正在睡眠進程的鏈表;
(5)設置觸摸屏狀態為空閑。
由于這里的初始化會占用一部分系統資源,所以把它們放在了打開設備時處理,而不是最初的設備初始化部分,這樣也是出于節省資源的考慮。
讀函數ts_read()
一旦用戶程序調用read()對觸摸屏進行讀操作,則驅動程序調用入口點函數ts_read()進行處理。如果此時沒有數據到來,且驅動程序選擇阻塞型操作,則調用interruptible_sleep_on(&queue->proc_list)將進程阻塞,并進入等待隊列,同時設置觸摸屏狀態為等待;如果選擇了非阻塞型操作,則程序在沒有數據到達的時候立即返回,然后用異步觸發fasync()來通知數據的到來。
在等待數據到來的過程中,如果有觸摸動作(筆中斷pen_irq)發生,則進入中斷處理程序。在中斷處理程序中對數據進行采樣和轉化,把當前坐標信息放入隊列中。在進程被喚醒后(使用wake_up_interruptible(&queue->proc_list)來喚醒進程),程序把位置坐標信息、事件序列信息等從隊列中取出,放入用戶空間(put_user),從而可以被用戶程序使用,避免了用戶直接和硬件打交道。
驅動程序的中斷處理函數
當筆中斷發生,程序進入中斷處理函數。在中斷處理函數中,將完成對兩個中斷進行處理,分別是外部的觸摸中斷(筆中斷)和SPI數據轉換中斷。與這兩個中斷對應的中斷處理函數,是觸摸屏軟件設計的關鍵所在。
驅動程序在中斷處理函數中使用定時器處理時間相關操作。定義函數set_timer_irq(),如下:
staticvoidset_timer_irq(structtimer_list*timer,intdelay){
del_timer(timer);
timer->expires=jiffies+delay;
add_timer(timer);
}
jiffies是一個表征系統自從啟動以來到當前為止所運行時鐘數的變量,delay是設定的延長時間(用時鐘數作為計數單位)。一旦時鐘數超過設定值,則觸發超時函數,在本程序中是handle_timeout( )。引入定時器的目的有兩個:一是可以較為精確地控制系統由于消除電平升降造成信號抖動所需要時間,二是能夠有效控制采樣坐標的數量,而不必引入占用大量系統資源的簡單延時函數。使用SPI中斷而產生大量坐標數據這一問題在文獻中沒有很好的解決辦法,只是簡單地降低SPI時鐘頻率以取較少的數據量。本設計中引入定時器,可以很好地解決上述問題。
在handle_timeout()函數中,程序利用條件選擇語句,對觸摸屏狀態值(ts_drv_state)進行判斷,如果是非Error狀態,則使能SPI,進入handle_spi_irq(),與ADS7843進行數據通訊。在handle_spi_irq()中,程序利用條件選擇語句,根據觸摸屏狀態值(ts_drv_state)來進行數據轉換操作,通過向觸摸屏控制芯片發送前文中提到的控制字,來得到X和Y方向的坐標。具體邏輯可參見程序流程圖。一旦一次轉換完成,程序將根據點擊狀態信息(state_counter)來鑒別點擊的性質,在cause_event()函數中,分別對點擊和移動做出了判斷。判定方法較為簡單,只需將前后兩次采樣坐標之差與移動閾值比較即可得出結論。此外,還區分了信號誤差和由于筆移動造成的坐標改變,判別閾值可以由用戶自己設定。
I/O控制
對于硬件各個參數,包括采樣時間、消除抖動開關、消除抖動時間,都可以通過I/O控制函數ioctl()在用戶程序里進行設定,避免每次都直接改變驅動程序,并重新編譯內核所帶來的時間開銷。本程序中對I/O控制函數的定義是:staticintts_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg);其中,參數cmd有兩個值,分別為:TS_PARAMS_GET和TS_PARAMS_SET,它們用來指出是獲取參數還是設定參數。用戶在調用這個函數的時候,只需要對這個參數按照事先約定的格式賦值,就可以方便地獲取或者改變觸摸屏當前參數,arg是指向所傳遞參數的指針。
結論
在獲得觸摸點的原始坐標(數值范圍由所選用的A/D轉換器位數決定)后,還要根據具體使用的液晶屏實際像素進行轉換,以方便圖形界面的后續開發。考慮到相鄰兩次的移動閾值,按照如下公式對觸摸屏坐標進行計算:
其中XV為觸摸點X坐標顯示值,XW為觸摸點X坐標測量值(原始坐標值),(1)、(2)、(3)式在觸摸屏初始化時得到,方法是任取觸摸屏X方向左側和右側各一點,以X△V=X△W=1,Xoffrer=0為初始值進行測量得到新的3個參數:X△V、X△W和Xoffrer(在實際使用中此項工作屬于校準零點偏移),然后這3個參數就不再變動,對于每次測量到的任意觸摸點原始坐標XW,直接代入(4)式求出觸摸點的像素顯示坐標XV。 其中,XV1為觸摸屏左側點坐標顯示值;XV2為觸摸屏右側點坐標顯示值;XW1為觸摸屏左側點坐標測量值;XW2為觸摸屏右側點坐標測量值。
本設計使用MicroWindows作為用戶界面,定制出每個桌面圖標的坐標區域,結合觸摸屏的采樣坐標,判斷是否在圖標區域坐標內,然后做出相應的事件處理。對于本設計中使用的開發平臺,液晶屏是320240點陣的,物理尺寸為: 80mm60mm,ADS7843選擇12位轉換精度,觸摸屏理論分辨率為80/212=0.020mm,但是由于電平干擾和觸摸動作發生時的物理干擾,實際的精度無法達到這個值。經過測試,在我們平臺上對同一點的點擊精度可以達到1.0mm。本驅動程序可以有效地區分點擊和移動信號,如果配合手寫識別軟件,能夠作為手寫板的底層驅動使用,實現手寫輸入。
責任編輯:gt
-
芯片
+關注
關注
454文章
50460瀏覽量
421968 -
嵌入式
+關注
關注
5071文章
19026瀏覽量
303507 -
微處理器
+關注
關注
11文章
2247瀏覽量
82331
發布評論請先 登錄
相關推薦
評論