1. 程式人生 > 其它 >UEFI開發探索76- YIE001PCIe開發板(09 介面和鍵盤控制)

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所示。
YIE1CG的介面圖
圖1 YIE1CG的介面

通過鍵盤控制LED燈的演示,只能通過視訊拍下轉換為GIF。不過,GIF檔案太大,就不貼出了。有條件的技術同好,可以按照本篇的方法,修改程式碼進行實驗。

Gitee地址:https://gitee.com/luobing4365/uefi-exolorer
專案所用ROM檔案位於:/ 76 YIE1CG下