关于《详解》第12.1节按键驱动的进一步阐述
生活随笔
收集整理的這篇文章主要介紹了
关于《详解》第12.1节按键驱动的进一步阐述
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
《詳解》12.1的按鍵驅(qū)動,是本書的最大失誤,應(yīng)大家的要求,我們很有必要對其進(jìn)行再次闡述。
???????? 注意標(biāo)題是“按鍵”驅(qū)動而非“鍵盤”驅(qū)動,按鍵往往是一個按鈕直接對應(yīng)于一個可中斷的GPIO,而鍵盤則有一個行列矩陣,有一個掃描的過程,由鍵盤控制器負(fù)責(zé)掃描、去抖動、得到鍵值等工作。
???????? 按鍵驅(qū)動的目的是在用戶調(diào)用read()的時候能夠讀出來正確的鍵值,如果用戶以阻塞方式打開,則在沒有按鍵事件的情況下,驅(qū)動應(yīng)切出本進(jìn)程,之后等待按鍵事件喚醒之。
??????? 因為在一個鍵被按下的時候,有一定時間的抖動,也就是說剛按下去的時候會彈來彈去數(shù)次,這些事件應(yīng)該被忽略。有的SoC的中斷控制器本身支持 debounce功能,會在硬件上去抖,就不再需要軟件去抖,否則,軟件上最好去抖動。去抖的常規(guī)思路是:當(dāng)一個鍵被按下的時候,啟動一個定時器延遲數(shù)十 ms,如果在定時器到期后,鍵還是按下的,就正式確認(rèn)一個按下事件,這樣,中間數(shù)十ms的彈來彈去就自動被過濾掉了。這就是在代碼清單12.8的ISR中 啟動一個定時器的原因,注意在第6行,只是將狀態(tài)置為了KEYSTATUS_DOWNX而不是KEYSTATUS_DOWN,在狀態(tài)是 KEYSTATUS_DOWNX的情況下,從代碼清單12.9(timer handler)的第6至13行可以看出,如果還是按下的,就確認(rèn)確實按下了,將狀態(tài)置為KEYSTATUS_DOWN。
??????? 為了實現(xiàn)阻塞方式地訪問,在沒有按鍵事件的情況下,如果用戶調(diào)用read(),本進(jìn)程應(yīng)該睡眠直到發(fā)生按鍵事件。在代碼清單12.11中 s3c2410_key_read()的第17行會通過interruptible_sleep_on()睡眠等待按鍵事件,而代碼清單12.9調(diào)用的 keyEvent()中做的事情就是講一個按鍵事件放入keydev.head和keydev.tail所管理的事件隊列(放入后將使得 keydev.tail != keydev.head成立),這樣,在第17行的interruptible_sleep_on()醒來后,跳轉(zhuǎn)執(zhí)行的第4行(keydev.tail != keydev.head)就可以得到滿足,從而執(zhí)行第8行的copy_to_user()將按鍵事件拷貝給用戶。
???????? 注意標(biāo)題是“按鍵”驅(qū)動而非“鍵盤”驅(qū)動,按鍵往往是一個按鈕直接對應(yīng)于一個可中斷的GPIO,而鍵盤則有一個行列矩陣,有一個掃描的過程,由鍵盤控制器負(fù)責(zé)掃描、去抖動、得到鍵值等工作。
???????? 按鍵驅(qū)動的目的是在用戶調(diào)用read()的時候能夠讀出來正確的鍵值,如果用戶以阻塞方式打開,則在沒有按鍵事件的情況下,驅(qū)動應(yīng)切出本進(jìn)程,之后等待按鍵事件喚醒之。
??????? 因為在一個鍵被按下的時候,有一定時間的抖動,也就是說剛按下去的時候會彈來彈去數(shù)次,這些事件應(yīng)該被忽略。有的SoC的中斷控制器本身支持 debounce功能,會在硬件上去抖,就不再需要軟件去抖,否則,軟件上最好去抖動。去抖的常規(guī)思路是:當(dāng)一個鍵被按下的時候,啟動一個定時器延遲數(shù)十 ms,如果在定時器到期后,鍵還是按下的,就正式確認(rèn)一個按下事件,這樣,中間數(shù)十ms的彈來彈去就自動被過濾掉了。這就是在代碼清單12.8的ISR中 啟動一個定時器的原因,注意在第6行,只是將狀態(tài)置為了KEYSTATUS_DOWNX而不是KEYSTATUS_DOWN,在狀態(tài)是 KEYSTATUS_DOWNX的情況下,從代碼清單12.9(timer handler)的第6至13行可以看出,如果還是按下的,就確認(rèn)確實按下了,將狀態(tài)置為KEYSTATUS_DOWN。
??????? 為了實現(xiàn)阻塞方式地訪問,在沒有按鍵事件的情況下,如果用戶調(diào)用read(),本進(jìn)程應(yīng)該睡眠直到發(fā)生按鍵事件。在代碼清單12.11中 s3c2410_key_read()的第17行會通過interruptible_sleep_on()睡眠等待按鍵事件,而代碼清單12.9調(diào)用的 keyEvent()中做的事情就是講一個按鍵事件放入keydev.head和keydev.tail所管理的事件隊列(放入后將使得 keydev.tail != keydev.head成立),這樣,在第17行的interruptible_sleep_on()醒來后,跳轉(zhuǎn)執(zhí)行的第4行(keydev.tail != keydev.head)就可以得到滿足,從而執(zhí)行第8行的copy_to_user()將按鍵事件拷貝給用戶。
總結(jié)
以上是生活随笔為你收集整理的关于《详解》第12.1节按键驱动的进一步阐述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android md 颜色,安卓MD(M
- 下一篇: 自动驾驶芯片_盘点全球自动驾驶芯片“战场