BIOS工程師手邊事—Keyboard


鍵盤作入計算機系統中的人機交互輸入設備,其重要性不言而喻。USB鍵盤驅動較爲複雜,需要USB控制器驅動,USB總線驅動和USB鍵盤驅動,內容比較繁雜。以後有空再來整理這方面的內容。今天重點整理一下筆記本中的矩陣鍵盤相關知識。

嵌入式BIOS部分:

1,配置矩陣鍵盤表:


查看如上圖所示的矩陣鍵盤絲印圖,對照鍵盤接口配置矩陣鍵盤表。雖然各個EC廠商代碼的矩陣鍵盤表配置方式都不一樣,但核心思想是一致的。矩陣鍵盤功能一般分爲三部分:

(1)普通鍵,直接將鍵值填入相應RC表中,有些矩陣位置沒有按鍵,但有IBM值,這時候也應該將其值錄入,一勞永逸,避免以後因使用不同國家的鍵盤而重複勞動。

(2)FN功能鍵,按住FN鍵的時候,置FN標誌位,和其他鍵組合使用。此時,該鍵值一般作爲索引,在代碼中,再寫FN功能鍵的各個功能函數。

(3)Overlay鍵,該鍵值也是索引,按NUMLOCK鍵時,驅動會下命令,置NUMLOCK指示燈,我們根據燈的狀態來區別所按下鍵是數字鍵功能還是做字母鍵功能。

注:如果OEM主板廠商不差錢,可以自已弄絲印圖和鍵盤接口,然後丟給鍵盤廠商,讓鍵盤廠商根據它們來開模。當然如果主板廠商不想這樣做,買別人現成的產品,根據鍵盤線排鍵盤接口也是可以的。

2,配置寄存器

除了配置矩陣鍵盤表,EC與HOST端訪問的“通路”也要打開。有一些相關寄存器需要配置:像鍵盤IBF的中斷使能,SCANIN中斷使能,還有Keyboard的邏輯設備初始化所牽涉的寄存器(當然,這部分也可以讓系統BIOS來配置)。

一般來說,嵌入式BIOS工程師做完以上兩種事,鍵盤的功能也就做完了。至於矩陣鍵盤掃描以及與HOST端的交互,不瞭解它們也不妨礙我們做項目,當然瞭解最好。當我們遇到比較棘手的問題,瞭解整個代碼流程,對於我們快速解決問題有大大的幫助。

鍵盤掃描流程:

1) SCANIN中斷,SCANIN有8根PIN,共亨一箇中斷。平時此8根PIN電平爲高,一旦按下矩陣鍵盤,就會觸發中斷,此時掃描程序正式開始。

2) 掃描時間並不是固定的,我們可以用1ms,2ms也可以用5ms的時間間隔來進行一次鍵盤掃描。

3) 掃描按照逐列掃描進行,每次將要掃描的列置低,其他列置高。如果有檢測到8個SCANIN有某個變低,就說明該列和該行有按鍵按下。按鍵被按鍵下,我們需要去抖,以防止有靜電或其他原因導致鍵盤掃描被誤觸發。去抖過後,我們就可以將掃描到的行列交叉點記錄的鍵盤送給相關處理函數,相關處理函數會將傳過來的行數列數值變成SCANCODE第二套碼值送給鍵盤BUFFER。

4) 鍵盤BUFFER傳送函數會將SCANCODE SET2轉換成SCANCODE SET1傳給上層驅動。雖說驅動可以決定接收SET1還是SET2的碼值,但我見過的驅動都要SET1,沒有要SET2的。不知道有沒有驅動能認SET2的?

 

系統BIOS部分:

1,解碼IO資源並使能鍵盤邏輯設備

解碼IO資源前,應該先看ISA配置空間是否支持subtractive decoding,如果支持,不需要我們做解碼工作,反之,我們需要手動decoding。

如果是EC,可以自已使能鍵盤邏輯設備,但如果是SuperIO,我們就必須在系統BIOS中添加使能邏輯設備的代碼。

使能之前,一定要先確定Base Address是2E/2F,4E/4F還是164E/164F。然後根據寄存器對來訪問邏輯設備。

OutPortB(0x2E,LDN);OutPortB(0x2F,LDNNumber);

   OutPortB(0x2E,ActiveByte); OutPortB(0x2F,1);

2,支援ACPI OS加載PS2鍵盤驅動

爲了使ACPI OS能夠正常加載PS2鍵盤驅動,我們需要在ASL中加入PS2 Device的宣告。這樣操作系統內核就在AML中找到HID爲PNP0303的Device後,變會加載PS2鍵盤驅動。

3,確保PS2鍵盤驅動在EFI環境下正常掛載

作爲系統BIOS工程師,首先要確保PS2驅動能夠正常掛載到controller上。爲此我們要確保兩件事:第一,我們的驅動會被正常編譯,即dsc文件有包含鍵盤驅動inf文件;第二,PS2鍵盤的DevicePath會被正常創建。對於針對Platform的BIOS工程師來說,只要這兩個條件滿足了,PS2鍵盤就能在EFI環境下正常使用。

下面我們來看下,DevicePath是如何被創建的:

在Isabus.c的IsaCreateDevice()函數中,有如下代碼段:


這裏就是創建DevicePath的地方了。但如何創建PS2鍵盤的DevicePath呢?根據代碼可以知道,IsaBus驅動在start時,會枚舉ISA設備,並讀取資源配置。


據此,我們追蹤DeviceEnumerate()或GetCurResource()函數的原型。


讓我們再來看下IsaDeviceLoopUp()的函數體:



很明顯, gPcatIsaAcpiDeviceList[]數組就是我們所要找尋的源頭。我們只需要將PS2鍵盤的資源和設備ID放入這個數組就可以了。




UDK2014是這樣來添加PS2鍵盤的DevicePath的。雖然各個BIOS廠商的做法和這個並不一樣,但思路都是一樣的。


那麼PS2鍵盤驅動Start函數做了什麼動作呢?

其實它主要工作就是爲控制檯提供一個鍵盤型輸入設備。EFI設計有一條理念就是模塊化。各個輸入設備驅動都是一個模塊,最終都是爲控制檯服務的。用戶只會使用gRT->ConIn而不會使用Ps2Keyboard.c的協議。PS2鍵盤作爲一個輸入設備,要爲控制檯提供的主要服務主要有:Reset(),ReadKeyStroke(),WaitForKey事件以及TimerEvent事件。

1,Reset

這個函數主要處理PS2鍵盤的初始化,並且重置鍵盤相關的變量和寄存器。這些過程需要下一些PS2命令來完成,這就牽涉到4個寄存器,當然從系統BIOS的角度來說,這四個寄存器可以看成是2個IO端口。這4個寄存器如下所示:


SystemBIOS讀命令步驟:

1)讀Data寄存器60H(有沒有這一步驟均可,嚴謹說來應該需要)

2)讀Status寄存器64H,OBF=1執行3,否則等待,超時退出

3)讀Data寄存器60H

SystemBIOS寫命令步驟:

1) 讀Status寄存器64H,IBF=0執行2,否則等待,超時退出

2) 寫Command寄存器64H

 

這些命令主要有:

#defineKEYBOARD_8042_COMMAND_READ                          0x20

#defineKEYBOARD_8042_COMMAND_WRITE                         0x60

#defineKEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE       0xA7

#defineKEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE        0xA8

#defineKEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST          0xAA

#defineKEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST  0xAB

#defineKEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE    0xAD

 

#defineKEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA             0xF4

#defineKEYBOARD_8048_COMMAND_RESET                         0xFF

#defineKEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET          0xF0

以及0xED,設置LED的命令

 

如果這些命令檢測沒有通過,這個設備就無法在EFI Console環境下使用。這個階段一般不會出問題。我曾遇到VxWorks下使用WindML庫,PS2鍵盤無法使用的問題,經過調試,我去掉一個Command檢測就好了(鍵盤firmware並不一定每個command都回應)。所以爲了兼容更多的鍵盤,這些命令保留最基本的就好,不需要用太多。

 

2,TimerEvent事件

這個事件一般設置爲20ms一次。把讀到的PS2 Set1 scancode轉成EFI所認識的UnicodeChar。


*****馬太福音25章25節:凡有的,還要加給他,叫他有餘。沒有的,連他所有的,也要奪過來*****

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章