os如何处理键盘的所有按键,显示or不显示,显示是如何显示
【0】README
0.1) source code and text decription are from orange’s implemention of a os , and for complete code , please visit 我待會上傳;
【1】 鍵盤輸入緩沖區
step1)緩沖區的數據結構如下:
step2)對緩沖區進行添加操作:(只是對 keyboard_handler 添加了一些代碼, 上述荔枝圖)
step3)修改后的init_keyboard
step4)初始化時鐘中斷
【2】用添加的新任務處理鍵盤操作
- 終端任務:我們的任務不僅會處理鍵盤操作、還會處理屏幕輸出等內容, 這些操作共同組成同一個任務——終端任務;
- keyboard_read():將掃描碼從緩沖區讀出,并打印;緩沖區的r_tail 指針移動, 而你是否記得將掃描碼存入緩沖區 是 緩沖區的 head指針移動;
【3】解析掃描碼
Attention:下面就是對 keyboard_read進行擴展了,像添加對小寫字符,數字的處理, 后面是 F1~F12的鍵處理, shift鍵處理,home鍵的處理等等;
Conclusion)修改的代碼內容包括:添加了鍵盤中斷緩沖區的代碼,修改了 keyboard_handler()函數 + init_keyboard()函數 + 對小寫字母和數字的處理代碼;
C1.1)我們給出修改后的代碼調用過程(重點在于 keyboard_handler()函數 + init_keyboard()函數 ):
C1.2)如何取到用戶鍵入的數據,以及顯示它們;
C2)運行結果為:
3.1)處理shift、alt、ctrl
注意:要將鍵的左右兩邊加以區分,如左shift和右shift的功能是不同的;(上上圖以及說明了)
3.2)處理所有按鍵
存在的問題-Problems 和 解決方法Solutions:
Problem1)如果掃描碼更加復雜一些,比如超過3個字符,如今的程序還不足以很好地處理;
因為當一個掃描碼有不止一個字符時, 實際上會產生不止一次中斷。看個荔枝:如果我們按一下Shift + A,產生的 0x2A0x1E0x9E0xAA 是4次中斷接收來的;
- step1) 我們的鍵盤控制器8042 接收來自 鍵盤編碼器8048 傳送過來的鍵入數據的相應掃描碼;
- step2) 8042收到掃描碼后,會把該掃描碼 編碼成 make code+break code的形式, 并將其放置到輸入緩沖區中,而8042的 輸入緩沖寄存器只有一個字節來存儲掃描碼;;
- step3) 8042告訴 中斷控制寄存器8259A 產生中斷, 交給鍵盤中斷處理程序去執行;(如果此時鍵盤又有新的鍵被按下,鍵盤控制器8042 將不再接收 鍵盤編碼器8048傳送過來的掃描碼,一直到緩沖區被清空,所以這就是為什么引入輸入緩沖區的原因.)
我們再來個補充(對比假設):
- 假設1)添加鍵盤輸入緩沖區(占用內存空間)后:只要鍵入數據,那么就會觸發鍵盤中斷處理程序,該程序會從 鍵盤控制器8042的輸入緩沖寄存器中讀取鍵入數據的掃描碼,并存儲在鍵盤輸入緩沖區中(之前已經建立在內存空間中了),也即讓8042的輸入緩沖區被清空,這樣8042才會接收 鍵盤編碼器8048傳送過來的鍵入數據的 掃描碼;
- 假設2) 如果不添加鍵盤輸入緩沖區(占用內存空間):只要鍵入數據,那么就會觸發鍵盤中斷處理程序,該程序會從 鍵盤控制器8042的輸入緩沖寄存器中讀取鍵入數據的掃描碼,并顯示該掃描碼對應的數據;
- 假設2中的問題):如果CPU沒有立即響應中斷處理程序 怎么辦? 這使得8042的輸入緩沖區不能被清空,反正一句話,就是要盡快讓鍵盤控制器8042的輸入緩沖器清空,這樣才能使得8042可以連續不斷地接受8048 傳送過來的掃描碼;
Solution1)我們將 從鍵盤控制器 8042 的輸入緩沖寄存器(只能緩沖一個字節的數據)中讀取數據的代碼從 keyboard_read 函數中抽取出來,并封裝到 get_byte_from_kbuf()函數中; 這樣對于掃描碼比較長的字符來說,我們可以通過 keyboard_read 函數多次讀取鍵盤緩沖區中的數據(鍵入數據的掃描碼而已);
鍵盤緩沖區的作用(function)(干貨):
- 有了鍵盤緩沖區, 8042 緩沖區 無需受到 task_tty 進程運行狀況的影響,因為鍵盤中斷處理程序 是將輸入的數據 保存到內存緩沖區去了,這樣鍵盤控制器8042的輸入緩沖器被清空,可以繼續接受8048傳送過來的掃描碼;
Problem2)關于非打印字符的問題: 如果按下 諸如 F1、F2這樣的功能鍵,系統會把它當做可打印字符來處理,從而打印出一個奇怪的符號;
Solutions2)我們的意思是: keyboard_read這個函數只是 負責讀取掃描碼就可以了(一次或多次調用get_byte_from_kbuf 函數 ),至于如何處理, 不應該由它來負責(因為不是所有鍵入的字符都是需要打印字符, 如Ctrl、Shift、大寫鎖定鍵、Esc鍵等);所以,我們又將打印字符的代碼抽取為 in_process ()函數, 在in_process()函數中,依據掃描碼判斷鍵入的字符是否需要打印;(具體代碼調用如下圖所示)
總結
以上是生活随笔為你收集整理的os如何处理键盘的所有按键,显示or不显示,显示是如何显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 待机时间长的安卓手机(待机时间长的安卓手
- 下一篇: 如何编译文件(gcc + nasm)