linux串口觸摸屏設(shè)計(jì)總結(jié)_第1頁
linux串口觸摸屏設(shè)計(jì)總結(jié)_第2頁
linux串口觸摸屏設(shè)計(jì)總結(jié)_第3頁
linux串口觸摸屏設(shè)計(jì)總結(jié)_第4頁
linux串口觸摸屏設(shè)計(jì)總結(jié)_第5頁
免費(fèi)預(yù)覽已結(jié)束,剩余1頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Linuxserialtouch設(shè)計(jì)總結(jié)概述:最近在做嵌入式 linux 下串口觸摸屏設(shè)計(jì),遇到一些問題,經(jīng)過查找資料和請(qǐng)教同事,總算把問題解決了,事后有把 linux 相關(guān)的內(nèi)核代碼仔細(xì)看了一遍,為了有點(diǎn)成果,特別寫了個(gè)總結(jié)。如有任何問題請(qǐng)聯(lián)系 ,轉(zhuǎn)載請(qǐng)標(biāo)明出處。系統(tǒng)資源:Linux:2.6.36UI:QT+TSLIB硬件資源不關(guān)心設(shè)計(jì)方法:有兩種實(shí)現(xiàn)途徑。1、是將要使用的串口單獨(dú)拿出來,作為一個(gè) platform 總線設(shè)備實(shí)現(xiàn),在嵌入式平臺(tái)mach文件里面, 加上串口中斷號(hào)和寄存器首地址, 然后將這個(gè)串口注冊(cè)成一個(gè)platform總線設(shè)備。 在驅(qū)動(dòng) probe 函數(shù)里面需要得到這個(gè)串口中斷

2、號(hào)以及寄存器映射地址, 通過寄存器映射地址設(shè)置串口波特率,數(shù)據(jù)位,停止位等,通過中斷號(hào)注冊(cè)中斷等,然后調(diào)用input_register_device 注冊(cè)一個(gè) input 設(shè)備。在中斷里面得到外面觸摸屏的數(shù)據(jù),然后根據(jù) inputtouch 協(xié)議上報(bào)觸摸數(shù)據(jù)。這種方法實(shí)現(xiàn)簡(jiǎn)單明了,不需要和 linux 的 tty,serio 等打交道。但是要求知道串口硬件 spec,比如寄存器等,而且這個(gè)串口就只能給觸摸屏使用了,不能作為 tty 使用。因?yàn)槭乔度胧介_發(fā),因此很容易知道硬件 spec,而且嵌入式平臺(tái)一旦確定,那么這個(gè)串口肯定就是給觸摸屏使用了。因此在嵌入式平臺(tái)上,推薦使用這個(gè)方法。2、是將串口

3、作為一個(gè) serio 總線設(shè)備,利用 linux 內(nèi)核提供 serio 總線驅(qū)動(dòng),通過設(shè)置對(duì)應(yīng)的串口,調(diào)用 serport 提供的函數(shù)將串口當(dāng)做 serio 總線設(shè)備,在驅(qū)動(dòng)里面需要按照 serio 總線設(shè)備驅(qū)動(dòng)的框架來實(shí)現(xiàn),這方面的例子 linux 里面有很多,比如 touchright.c,在模塊 init 函數(shù)里面調(diào)用 serio_register_driver 注冊(cè) serio 總線設(shè)備驅(qū)動(dòng),如果 serio 總線上對(duì)應(yīng)的 serio 設(shè)備存在,就調(diào)用 connect 函數(shù),在這個(gè)函數(shù)里面調(diào)用 input_register_device 注冊(cè)一個(gè) input 設(shè)備。具體驅(qū)動(dòng)不再分析了,

4、很簡(jiǎn)單,相信各位都能看的懂。至此,兩種方法都實(shí)現(xiàn)了串口觸摸屏的驅(qū)動(dòng),講到這里是不是就完了,非也,本文的重點(diǎn)還在后面,請(qǐng)看下面分析:第一種方法只要驅(qū)動(dòng)模塊被加載,就會(huì)在/dev/input 下面創(chuàng)建一個(gè) eventx 節(jié)點(diǎn),tslib 就能訪問這個(gè)節(jié)點(diǎn),獲得觸摸坐標(biāo),然后送給 qto第二種方法驅(qū)動(dòng)模塊加載后,并沒有創(chuàng)建 eventx 節(jié)點(diǎn),也就是說 connect 函數(shù)沒有被調(diào)用,按照 linux 驅(qū)動(dòng)模型來看,就是 serio 總線上還沒有對(duì)應(yīng)的 serio 設(shè)備,因此驅(qū)動(dòng)加載時(shí)沒有對(duì)應(yīng)的設(shè)備,就不會(huì)調(diào)用 connect 函數(shù),這時(shí)的串口還是作為一個(gè) linuxtty 設(shè)備存在。我遇到的問題就

5、是 serio 驅(qū)動(dòng)加載了,但是沒有創(chuàng)建 eventx 節(jié)點(diǎn),查找資料也只有一個(gè)說是要把 tty 設(shè)置成 N_MOUSE,然后讀,說的不清楚,也不知道怎么實(shí)現(xiàn),經(jīng)過自己摸索,終于把問題解決了。Linux 啟動(dòng)后串口形式:Linux 一啟動(dòng)是將串口作為 tty 來設(shè)置的??聪碌恼{(diào)用:start_kernelinit/main.c 大家對(duì)這個(gè)函數(shù)不陌生吧,linux 啟動(dòng)過程中重要的一個(gè)函數(shù)console_init();drivers/tty/tty_io.ctty_register_ldisc(N_TTY,&tty_ldisc_N_TTY);drivers/tty/tty_idisc.c給串口注

6、冊(cè)一個(gè) tty 鏈路層處理函數(shù) ops?,F(xiàn)在我們需要寫一個(gè)上層的應(yīng)用程序,對(duì)這個(gè) tty 進(jìn)行設(shè)置,需要設(shè)置波特率,數(shù)據(jù)位,停止位等,最重要的是要將這個(gè) tty 設(shè)備設(shè)置成一個(gè) serio 總線設(shè)備,然后把它注冊(cè)在 serio 總線上,請(qǐng)看下面的代碼:fd=open(device,O_RDWR|O_NOCTTY|O_NONBLOCK);if(fdflags,type-speed);ldisc=N_MOUSE;if(ioctl(fd,TIOCSETD,&ldisc)fprintf(stderr,inputattach:cantsetlinediscipline);returnEXIT_FAILU

7、RE;devt=type-type|(id8)|(extraops-open(tty)ld-ops 就是 serport 注冊(cè)的 serport_ldiscstaticintserport_ldisc_open(structtty_struct*tty)drivers/input/serio/serport.c這個(gè)函數(shù)里面會(huì)創(chuàng)建一個(gè) serport 結(jié)構(gòu)體,并初始化至此,已經(jīng)給串口增加了一個(gè) N_MOUSE 的鏈路層,并且把鏈路層的處理函數(shù)也注冊(cè)進(jìn)去了。這個(gè)串口當(dāng)前的鏈路層就是 N_MOUSE。目前為止串口還只是個(gè) tty 設(shè)備,并沒有注冊(cè)到 serio總線上。繼續(xù)看我們的應(yīng)用程序:devt=

8、type-type|(id8)|(extraops-ioctl(tty,file,cmd,arg);staticintserport_ldisc_ioctl(structtty_struct*tty,structfile*file,unsignedintcmd,unsignedlongarg)設(shè)置to=type&0 x000000ff;serport-id.id=(type&0 x0000ff00)8;serport-id.extra=(type&0 x00ff0000)16;這里三個(gè)值一定要和 serio 總線驅(qū)動(dòng)里面對(duì)應(yīng)的值一致,serio 總線就是靠它們來給設(shè)

9、備和驅(qū)動(dòng)建立聯(lián)系的。調(diào)用read(fd,NULL,0);跟蹤代碼到內(nèi)核層 tty_read:staticssize_ttty_read(structfile*file,char_user*buf,size_tcount,loff_t*ppos)(ld-ops-read)(tty,file,buf,count)這個(gè) ld 就是 tty 當(dāng)前的鏈路層結(jié)構(gòu),上面我們已經(jīng)設(shè)置N_MOUSE 為 tty 的當(dāng)前鏈路層,因此 ld-ops 就是 serport 注冊(cè)的 serport_ldiscstaticssize_tserport_ldisc_read(structtty_struct*tty,str

10、uctfile*file,unsignedchar_user*buf,size_tnr)serio_register_port(serport-serio);serio_init_port(serio);serio_queue_event(serio,owner,SERIO_REGISTER_PORT);注冊(cè)一個(gè) serio 總線設(shè)備,關(guān)于 serio 總線,網(wǎng)絡(luò)有很多資料介紹,這里就不說了。至此,我們的串口設(shè)備已經(jīng)當(dāng)做 serio 總線設(shè)備注冊(cè)在 serio 總線上了,如果相應(yīng)的驅(qū)動(dòng)也在serio 總線上,就會(huì)進(jìn)行設(shè)備和驅(qū)動(dòng)的匹配,然后調(diào)用驅(qū)動(dòng)里面的 connect 函數(shù),在這個(gè)函數(shù)里面就會(huì)

11、創(chuàng)建 input 節(jié)點(diǎn)。我們的驅(qū)動(dòng)和設(shè)備已經(jīng)運(yùn)行起來了,現(xiàn)在看看數(shù)據(jù)是如何傳遞的先看具體串口中斷函數(shù):我們以 altera_uart.c 為例:altera_uart_interruptaltera_uart_rx_chars(pp)tty_flip_buffer_push(port-state-port.tty);flush_to_ldisc(&tty-buf.work);disc-ops-receive_buf(tty,char_buf,flag_buf,count);disc-ops 就是 serport 注冊(cè)的 serport_ldiscstaticvoidserport_ldisc_

12、receive(structtty_struct*tty,constunsignedchar*cp,char*fp,intcount)serio_interrupt(serport-serio,cpi,ch_flags);ret=serio-drv-interrupt(serio,data,dfl);drv-interrupt 就是我們驅(qū)動(dòng)函數(shù)提供一個(gè)函數(shù),它每次接受一個(gè)字符,在這個(gè)函數(shù)里面,接受到足夠信息后,就能得到觸摸屏坐標(biāo)信息,然后通過 input_report 上報(bào)上去??纯磾?shù)據(jù)處理流程圖:總結(jié):Dataflowandfunctioncallsinwritingandreading要想讓基于 serio 總線驅(qū)動(dòng)的用口觸摸屏能正常工作,在 linux 內(nèi)核需要加載驅(qū)動(dòng)模塊,ser

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論