- 論壇徽章:
- 0
|
最近想學(xué)習(xí)下usb驅(qū)動,剛好手頭有《圈圈教你學(xué)usb》書和實驗板,有一章自定義設(shè)備和 usb-skeleton 驅(qū)動大致吻合。實踐出真知嘛,當(dāng)然得搞一搞。固件程序大概改了下,只用了批量端點2,中斷端點1代碼全部干掉,簡單起見,主機發(fā)數(shù)據(jù),跑馬燈;主機讀取數(shù)據(jù),用戶按下鍵盤就返回8字節(jié)數(shù)據(jù),當(dāng)然抬起也會發(fā)(固件基本不需要改)。當(dāng)然不按就不干活。skeleton驅(qū)動改了VENDOR_ID和PRODUCT_ID,基本就可以匹配了。
測試環(huán)境:
[linux@localhost ~]$ cat /etc/issue
CentOS Linux release 6.0 (Final)
Kernel \r on an \m
[linux@localhost ~]$ cat /proc/version
Linux version 2.6.38 (linux@localhost.ada) (gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) ) #1 SMP Tue Sep 13 09:03:59 EDT 2011
用戶執(zhí)行操作:
[root@localhost hid_test]# gcc skeleton_test_01.c
[root@localhost hid_test]# ./a.out
Open /dev/skel0 success!
^C
[root@localhost hid_test]# ./a.out
Open /dev/skel0 success!
read.len = -1. errno = 5
read: Input/output error
[root@localhost hid_test]#
內(nèi)核打印顯示(只顯示問題所在,其他見附件):
……
Mar 1 21:29:17 localhost kernel: Now leave skel_read: rv = -512 //用戶ctrl+c之后返回。(正常)
Mar 1 21:29:17 localhost kernel: Now in skel_read_bulk_callback. //你怎么也返回了,哥沒按鍵盤呀。
Mar 1 21:29:17 localhost kernel: read_callback_times = 0 urb->status = -2 //提交urb的回調(diào)也執(zhí)行了? 好快呀!而且還返回個錯誤(必須得,因為沒按鍵盤)。
Mar 1 21:29:17 localhost kernel: Now leave skel_read_bulk_callback.
Mar 1 21:29:17 localhost kernel: Now in skel_release.
……
Mar 1 21:29:19 localhost kernel: usb_skeleton: skel_do_read_io - failed submitting read urb, error -22 //再次打開設(shè)備讀,提交urb直接失敗,不會吧
Mar 1 21:29:19 localhost kernel: Now leave skel_do_read_io: rv = -5 //IO error. 用戶層返回 read: Input/output error.
……
調(diào)試中的問題:
processed_urb 這玩意沒用上嘛,而且probe中也沒初始化為1.導(dǎo)致第一次讀直接掛死在wait_for_completion(&dev->bulk_in_completion)。
如果有兄弟知道這玩意有什么特殊用途,告知下!
重點疑問:
用戶程序結(jié)束后只要有預(yù)讀,則批量輸入也直接結(jié)束,返回-2; 而且下次重新填充提交urb就會失敗,返回-22。也就是說讀一次失敗,設(shè)備就沒法工作了。當(dāng)然也會返回-75,-5 之類。簡單說下預(yù)讀,驅(qū)動作者意圖,假設(shè)緩存中有8字節(jié),如果本次要求讀8字節(jié),夠了讀取8字節(jié)直接返回,不需要啟動IO(在這里就是提交urb);如果讀4字節(jié),當(dāng)然剩下4字節(jié),也無需啟動IO;如果用戶要求讀12字節(jié),直接以8字節(jié)返回,并且開啟IO(此時應(yīng)該不管應(yīng)用程序結(jié)束不結(jié)束,我都要讀,和應(yīng)用程序無關(guān))。
測試寫沒有問題,中途干死,也可以繼續(xù)流水燈。
測試讀的時候,沒有預(yù)讀,程序一切正常,用戶態(tài)阻塞,直到我按鍵。程序正常結(jié)束,也可以再次啟動。一切完好(每次讀8字節(jié))。
如果有預(yù)讀,則就是上面看到的結(jié)果,也可以改用戶程序每次讀取8個以上字節(jié),關(guān)閉應(yīng)用程序也能保證驅(qū)動有預(yù)讀,同樣下次再次開啟失敗。
所以不太明白,為什么有預(yù)讀,用戶程序結(jié)束了,提交的urb立馬也返回出錯了。退一步講,即使這一次出錯,下次再次填充,提交urb也不該提交不上呀。是否有兄弟對此有熟悉,指點一二。
附件:
skele_test.rar
(11.62 KB, 下載次數(shù): 67)
2012-03-01 22:53 上傳
點擊文件名下載附件
|
|