UEFI開發探索76- YIE001PCIe開發板(09 介面和鍵盤控制)
技術標籤:UEFI開發UEFIpci-eOption ROM底層應用開發YIE001
(請保留-> 作者: 羅冰 https://blog.csdn.net/luobing4365)
YIE001PCIe開發板之介面和鍵盤控制
在開發板YIE001上進行開發,實際上和之前部落格中開發UEFI應用,並沒有本質的區別。所要注意的,是在Option ROM被BIOS載入之時,所用的UEFI機制以及Protocol是否能正常使用。
一般來說, GraphicsOutput Protocol和ConOut Protocol是可以正常使用的。但是,其他的Protocol,比如建立Event,就很難說了。筆者目前測試的機器上,在載入Option ROM時,建立的Event完全無法按照預期運作。而同樣的程式碼,在同一機器的UEFI Shell下測試卻是正常的。
本篇程式碼的程式設計過程如下。
1 圖形支援和漢字支援
UEFI開發探索中的程式碼,特別是圖形和漢字部分,是從我的開源專案Foxdisk中移植過來的。針對UEFI的機制,進行了改動。所以,在部落格中的程式碼,同文件名的,其內容都差不多。
當然,隨著各個課題的展開,程式碼也在不斷地修改。甚至對我而言,也很難分清楚目前所用的檔案是什麼時候修改的。比如近期又在處理鍵盤的原始檔中,添加了檢查鍵盤按鍵的非阻塞處理函式CheckKey()。
我盡力維持一個鬆散而邏輯一致的結構,保證原始檔可以直接使用。處理同一硬體的或者同一邏輯層的程式碼,基本上會在相同的原始檔中。
以下列出了原始檔的功能:
表1 原始檔的功能
原始檔 | 引腳名稱 |
---|---|
Graphic.c, Graphic.h | 功能 |
Keyboard.c, Keyboard.h | 鍵盤處理 |
Window.c, Window.h | 介面相關的程式碼,比如背景設定等 |
Font.c, Font.h | 文字的顯示,包括漢字、英文的顯示 |
Common.c, Common.h | 提供各種Protocol例項,以及共用的一些函式 |
將以上的檔案,拷貝到之前構建好的Option ROM框架程式碼的資料夾下,修改相應的INF檔案,就可以直接使用了。
對於漢字的顯示機制,之前的部落格中已經討論得比較多了,可以檢視下之前的部落格及程式碼。
不過,部落格中討論的議題還是比較分散的。《UEFI程式設計實踐》的書中,為了編譯閱讀,將這些議題整理成章了。考慮到版權問題,各種漢字型檔的提取工具也重新編寫了。新書釋出的時候,我將會把程式碼和工具在Gitee和GitHub上共享,有興趣的技術同好到時可以直接去下載使用。
2 介面及鍵盤控制程式設計
Option ROM的程式碼,只有在BIOS載入到記憶體中才能執行。在這點上,開發板YIE001和YIE002有很大不同,YIE001畢竟不是獨立的MCU,無法獨立執行。
本篇的程式碼,將鍵盤的控制與YIE001的硬體控制聯絡起來了。具體實現程式碼如下:
VOID HelloUEFI(VOID)
{
UINT64 flag;
EFI_INPUT_KEY key={0,0};
UINT8 *s_text = "Alasse' aure,"; //《魔戒》精靈語的 “你好,日安”
UINT8 *s_text1 = "歡迎進入UEFI的世界!";
UINT8 *s_text2 = "按'ESC'鍵退出此介面";
flag = InintGloabalProtocols(GRAPHICS_OUTPUT);
Print(L"flag=%x\n",flag);
//圖形顯示測試
SwitchGraphicsMode(TRUE);
SetBKG(&(gColorTable[DEEPBLUE]));
draw_string(s_text, 110, 60, &MyFontArray, &(gColorTable[WHITE]));
draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[WHITE]));
draw_string(s_text2, 135, 140, &MyFontArray1, &(gColorTable[YELLOW]));
while(key.ScanCode!=0x17) //ESC
{
GetKey(&key);
if(key.ScanCode ==1 ) //UP
draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[DEEPBLUE]));
else if(key.ScanCode ==2 ) //DOWN
draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[WHITE]));
if(key.UnicodeChar == 0x31)
SetLed(MyIoBaseAddr,LED1,LEDON);
if(key.UnicodeChar == 0x32)
SetLed(MyIoBaseAddr,LED2,LEDON);
if(key.UnicodeChar == 0x33)
SetLed(MyIoBaseAddr,LED1,LEDOFF);
if(key.UnicodeChar == 0x34)
SetLed(MyIoBaseAddr,LED2,LEDOFF);
}
SetMyMode(OldGraphicsMode);
SwitchGraphicsMode(FALSE);
}
程式碼的邏輯並不複雜,在設定了圖形模式,顯示相應的提示字元後,直接進入按鍵獲取的迴圈。只有接受到使用者的ESC按鍵後,才會退出迴圈。
方向鍵的上下鍵用來控制螢幕上字串s_text1的顯示和消除;數字鍵1、2、3和4,分別用來控制LED1、LED2的亮和滅。
3 測試
編譯命令如下:
C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc -m RobinPkg\Drivers\YIE1CG\YIE1CG.inf -a X64
按照UEFI開發探索75介紹的方法,將YIE1CG.rom刷入YIE001的Flash中,並插在實際的機器上進行測試(也可以不刷入,使用UEFI開發探索71中介紹的方法,使用load命令測試)。
Option ROM的介面顯示如圖1所示。
圖1 YIE1CG的介面
通過鍵盤控制LED燈的演示,只能通過視訊拍下轉換為GIF。不過,GIF檔案太大,就不貼出了。有條件的技術同好,可以按照本篇的方法,修改程式碼進行實驗。
Gitee地址:https://gitee.com/luobing4365/uefi-exolorer
專案所用ROM檔案位於:/ 76 YIE1CG下