


版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Linux serial touch 設(shè)計(jì)總結(jié)概述:最近在做嵌入式linux下串口觸摸屏設(shè)計(jì),遇到一些問(wèn)題,經(jīng)過(guò)查找資料和請(qǐng)教同事, 總算把問(wèn)題解決了,事后有把linux相關(guān)的內(nèi)核代碼仔細(xì)看了一遍,為了有點(diǎn)成果,特別寫(xiě)了個(gè)總結(jié)。,轉(zhuǎn)載請(qǐng)標(biāo)明出處。系統(tǒng)資源:Linux: 2636Ul: QT+TSLIB硬件資源不關(guān)心設(shè)計(jì)方法:有兩種實(shí)現(xiàn)途徑。1、是將要使用的串口單獨(dú)拿出來(lái),作為一個(gè)platform總線(xiàn)設(shè)備實(shí)現(xiàn),在嵌入式平臺(tái)mach文件里面,加上串口中斷號(hào)和寄存器首地址,然后將這個(gè)串口注冊(cè)成 一個(gè)platform總線(xiàn)設(shè)備。在驅(qū)動(dòng) probe函數(shù)里面需要得到這個(gè)串口中斷號(hào)以及 寄存器映射地址,通過(guò)寄
2、存器映射地址設(shè)置串口波特率,數(shù)據(jù)位,停止位等,通過(guò)中斷號(hào)注冊(cè)中斷等,然后調(diào)用in put_register_device注冊(cè)一個(gè)in put設(shè)備。在中斷里面得到外面觸摸屏的數(shù)據(jù),然后根據(jù)in put touch協(xié)議上報(bào)觸摸數(shù)據(jù)。這種方法實(shí)現(xiàn)簡(jiǎn)單明了,不需要和linux的tty,serio等打交道。但是要求知道串口硬件spec,比如寄存器等,而且這個(gè)串口就只能給觸摸屏使用了,不能作 為tty使用。因?yàn)槭乔度胧介_(kāi)發(fā),因此很容易知道硬件spec,而且嵌入式平臺(tái)一旦確定,那么這個(gè)串口肯定就是給觸摸屏使用了。因此在嵌入式平臺(tái)上,推 薦使用這個(gè)方法。2、是將串口作為一個(gè) serio總線(xiàn)設(shè)備,利用linux
3、內(nèi)核提供serio總線(xiàn)驅(qū)動(dòng),通過(guò)設(shè)置對(duì)應(yīng)的串口,調(diào)用 serport提供的函數(shù)將串口當(dāng)做serio總線(xiàn)設(shè)備,在驅(qū)動(dòng)里面需要按照serio總線(xiàn)設(shè)備驅(qū)動(dòng)的框架來(lái)實(shí)現(xiàn),這方面的例子linux里面有很多,比如touchright.c,在模塊in it函數(shù)里面調(diào)用 serio_register_driver注冊(cè)serio總線(xiàn) 設(shè)備驅(qū)動(dòng),如果 serio總線(xiàn)上對(duì)應(yīng)的serio設(shè)備存在,就調(diào)用 connect函數(shù),在 這個(gè)函數(shù)里面調(diào)用in put_register_device注冊(cè)一個(gè)in put設(shè)備。具體驅(qū)動(dòng)不再分 析了,很簡(jiǎn)單,相信各位都能看的懂。至此,兩種方法都實(shí)現(xiàn)了串口觸摸屏的驅(qū)動(dòng),講到這里是不是就
4、完了,非也,本文的重點(diǎn)還在后面,請(qǐng)看下面分析:第一種方法只要驅(qū)動(dòng)模塊被加載,就會(huì)在/dev/input下面創(chuàng)建一個(gè)eventx節(jié)點(diǎn),tslib就能訪(fǎng)問(wèn)這個(gè)節(jié)點(diǎn),獲得觸摸坐標(biāo),然后送給qt。第二種方法驅(qū)動(dòng)模塊加載后,并沒(méi)有創(chuàng)建eventx節(jié)點(diǎn),也就是說(shuō)connect函數(shù)沒(méi)有被調(diào)用,按照l(shuí)inux驅(qū)動(dòng)模型來(lái)看,就是 serio總線(xiàn)上還沒(méi)有對(duì)應(yīng)的serio設(shè)備,因此驅(qū)動(dòng)加載時(shí)沒(méi)有對(duì)應(yīng)的設(shè)備,就不會(huì)調(diào)用connect函數(shù),這時(shí)的串口還是作為一個(gè)linux tty設(shè)備存在。我遇到的問(wèn)題就是 serio驅(qū)動(dòng)加載了,但是沒(méi)有創(chuàng)建eventx節(jié)點(diǎn),查找資料也只有一個(gè)說(shuō)是要把tty設(shè)置成N_MOUSE,然后讀,
5、說(shuō)的不清楚,也不知道怎么實(shí)現(xiàn),經(jīng)過(guò)自己 摸索,終于把問(wèn)題解決了。Lin ux啟動(dòng)后串口形式:Linux 啟動(dòng)是將串口作為tty來(lái)設(shè)置的??聪碌恼{(diào)用:start_kernelinit/main.c大家對(duì)這個(gè)函數(shù)不陌生吧,linux啟動(dòng)過(guò)程中重要的一個(gè)函數(shù)con sole_ in it();drivers/tty/tty_io.ctty_register_ldisc(N_TTY, &tty_ldisc_N_TTY); drivers/tty/tty_idisc.c給串口注冊(cè)一個(gè)tty鏈路層處理函數(shù)ops。Source hl«s involved in serial managem
6、ent how they are connected and how flows.00000/L o o o o /停serio 總現(xiàn)在我們需要寫(xiě)一個(gè)上層的使用程序,對(duì)這個(gè)tty進(jìn)行設(shè)置,需要設(shè)置波特率,數(shù)據(jù)位,止位等,最重要的是要將這個(gè)tty設(shè)備設(shè)置成一個(gè)serio總線(xiàn)設(shè)備,然后把它注冊(cè)在線(xiàn)上,請(qǐng)看下面的代碼:fd = ope n( device, O_RDWR | O_NOCTTY | O_NONBLOCK);if (fd < 0) fprintf(stderr, "inputattach: '%s' - %sn", device, strerro
7、r(errno);return 1;setline(fd, type_>flags, type->speed);ldisc = N_MOUSE;if (ioctl(fd, TIOCSETD, &ldisc) fprintf(stderr, "inputattach: can't set line disciplinen”); return EXIT_FAILURE;devt = type->type | (id << 8) | (extra << 16);if (ioctl(fd, SPIOCSTYPE, & devt
8、) fprin tf(stderr, "in putattach: can't set device typen"); return EXIT_FAILURE;read(fd, NULL, 0);里面的device就是對(duì)應(yīng)要使用的那個(gè)串口,linux里面一般是/dev/ttySO,首先是打開(kāi)串口ope n( device, O_RDWR | O_NOCTTY | O_NONBLOCK)接著設(shè)置波特率等setline(fd, CS8, B9600);static void setl in e(i nt fd, int flags, int speed)struct t
9、ermios t;tcgetattr(fd, &t);t.c_cflag = flags | CREAD | HUPCL | CLOCAL;t.c_iflag = IGNBRK | IGNPAR;t.c_oflag = 0;t.c_lflag = 0;t.c_ccVMIN = 1;t.c_ccVTIME = 0; cfsetispeed( &t, speed);cfsetospeed(&t, speed); tcsetattr(fd, TCSANOW, &t);接下來(lái)就是重點(diǎn)了ldisc = N_MOUSE;if (ioctl(fd, TIOCSETD, &am
10、p;ldisc)跟蹤代碼到內(nèi)核層ioctl:long tty_ioctl(struct file *file, un sig ned int cmd, un sig ned long arg) drivers/tty/tty_io.ccase TIOCSETD:return tiocsetd(tty, p); drivers/tty/tty_io.c tty_set_ldisc(tty, ldisc); drivers/tty/tty_idisc.c , ldisc 等于 N_MOUSE n ew_ldisc = tty_ldisc_get(ldisc);ldops = get_ldops(d
11、isc);這段代碼需要得到N_MOUSE的鏈路層,先在tty_ldiscs里面查找是否有 N_MOUSE鏈路層的處理函數(shù)ops,如果沒(méi)有,就需要加載serport模塊,看看這個(gè)模塊init函數(shù)retval = tty_register_ldisc(N_MOUSE, &serport_ldisc);注冊(cè)一個(gè)N_MOUSE鏈路層的處理函數(shù)ops創(chuàng)建一個(gè)新的 N_MOUSE鏈路層new_ldisc,接著調(diào)用tty_ldisc_assign(tty, new_ldisc);把新的鏈路層放在 tty 里面retval = tty_ldisc_ope n( tty, n ew_ldisc); 打開(kāi)
12、這個(gè)新的鏈路層ret = ld->ops->open(tty)ld->ops 就是 serport 注冊(cè)的 serport_ldiscstatic int serport_ldisc_ope n( struct tty_struct *tty) drivers/i nput/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è)備,并沒(méi)有注冊(cè)到serio總線(xiàn)上。繼續(xù)看我們的使用程序:devt =
13、 type->type | (id << 8) | (extra << 16);if (ioctl(fd, SPIOCSTYPE, & devt) fprin tf(stderr, "in putattach: can't set device typen");return EXIT_FAILURE;調(diào)用long tty_ioctl(struct file *file, un sig ned int cmd, un sig ned long arg) drivers/tty/tty_io.cretval = ld->ops
14、->ioctl(tty, file, cmd, arg);static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, un sig ned int cmd, un sig ned long arg)設(shè)置serport->to = type & OxOOOOOOff;serport->id.id = (type & OxOOOOffOO) >> 8; serport->id.extra = (type & OxOOffOOOO) &g
15、t;> 16;這里三個(gè)值一定要和 serio總線(xiàn)驅(qū)動(dòng)里面對(duì)應(yīng)的值一致,serio總線(xiàn)就是靠它們來(lái)給設(shè)備和驅(qū)動(dòng)建立聯(lián)系的。調(diào)用read(fd, NULL, 0);跟蹤代碼到內(nèi)核層 tty_read :static ssize_t tty_read(struct file *file, char _user *buf, size_t count,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
16、注冊(cè)的serport_ldiscstatic ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, un sig ned char _user* buf, size_t nr)serio_register_port(serport->serio);serio_ ini t_port(serio); serio_queue_eve nt(serio, owner, SERIO_REGISTER_PORT);注冊(cè)一個(gè)serio總線(xiàn)設(shè)備,關(guān)于serio總線(xiàn),網(wǎng)絡(luò)有很多資料介紹,這里就不說(shuō)了。 至此,我們的
17、串口設(shè)備已經(jīng)當(dāng)做serio總線(xiàn)設(shè)備注冊(cè)在serio總線(xiàn)上了,如果相應(yīng)的驅(qū)動(dòng)也在serio總線(xiàn)上,就會(huì)進(jìn)行設(shè)備和驅(qū)動(dòng)的匹配,然后調(diào)用驅(qū)動(dòng)里面的connect函數(shù),在這個(gè)函數(shù)里面就會(huì)創(chuàng)建in put節(jié)點(diǎn)。我們的驅(qū)動(dòng)和設(shè)備已經(jīng)運(yùn)行起來(lái)了,現(xiàn)在看看數(shù)據(jù)是如何傳遞的 先看具體串口中斷函數(shù):我們以altera_uart.c為例:altera_uart_i nterruptaltera_uart_rx_chars(pp) tty_flip_buffer_push(port->state->port.tty);flush_to_ldisc(&tty->buf.work);disc-&
18、gt;ops->receive_buf(tty, char_buf,flag_buf, count); disc->ops 就是 serport 注冊(cè)的 serport_ldisc static void serport_ldisc_receive(struct tty_struct *tty, const un sig ned char*cp, char *fp, int count)serio_i nterrupt(serport->serio, cpi, ch_flags); ret = serio->drv ->in terrupt(serio, data, dfl);drv->interrupt就是我們驅(qū)動(dòng)函數(shù)提供一個(gè)函數(shù),它每次接受一個(gè)字符,在這個(gè)函數(shù)里面,接受到足夠信息后,就能得到觸摸屏坐標(biāo)信息,然后通過(guò)input_report上報(bào)上去??纯磾?shù)據(jù)處理流程圖:Data flow and function
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 武漢學(xué)院《微生物生理學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 漯河醫(yī)學(xué)高等專(zhuān)科學(xué)校《控制電機(jī)》2023-2024學(xué)年第二學(xué)期期末試卷
- 湛江市高中畢業(yè)班調(diào)研測(cè)試?yán)砭C化學(xué)試題
- 基礎(chǔ)輻射安全培訓(xùn)
- 2025綜合布線(xiàn)系統(tǒng)安裝合同范本
- 2025標(biāo)準(zhǔn)自建房施工合同模板
- 2025國(guó)際建筑工程分包合同范本
- 2025版短期勞動(dòng)合同范本下載
- 2025廣東房屋租賃合同范本
- 2025存量房買(mǎi)賣(mài)合同范本及司法解釋
- 2025年吉林鐵道職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)完整
- 2025年濟(jì)源職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)匯編
- 護(hù)工合同協(xié)議書(shū)樣本
- 航空發(fā)動(dòng)機(jī)控制知到智慧樹(shù)章節(jié)測(cè)試課后答案2024年秋中國(guó)民航大學(xué)
- 廣東省2025年高三高考模擬地理試卷試題(含答案詳解)
- 濕法厭氧消化副產(chǎn)物資源化-深度研究
- 斯大林格勒保衛(wèi)戰(zhàn)
- 電氣設(shè)備維護(hù)與安全使用
- 2024年中國(guó)海上綠色氫醇氨行業(yè)市場(chǎng)發(fā)展前景研究報(bào)告-智研咨詢(xún)發(fā)布
- DB33T 2216-2019 人民調(diào)解工作規(guī)范
- 2025年中國(guó)華電集團(tuán)公司招聘筆試參考題庫(kù)含答案解析
評(píng)論
0/150
提交評(píng)論