iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0

嗨我是k66,前一篇我們實作顯示系統時間,在那之前前五篇我們實作Logo,本篇要來實作按鍵功能—按ESC退出(詳細欲實現功能請參考本系列文Day11)。

實作按鍵功能主要會使用到4個:EFI_EVENTgBS->CreateEventgBS->WaitForEventgST->ConIn->ReadKeyStroke

放碼上來!程式碼連結


  • 架構(跟Day18幾乎一樣)
|-edk2space\edk2\ #若非跟著系列文看上來的新手,edk2安裝請查看[Day7](https://ithelp.ithome.com.tw/articles/10317443)
    |-OinkBLPkg
        |-ESCevent.c #重點
        |-OinkBL.inf
        |-OinkBLPkg.dsc
  • OinkBLPkg.dsc
    內容不變就能跑
  • OinkBL.inf
    改[Sources]即可
    [Sources]
      # Time.c
      # Time.h
      ESCevent.c
  • 本篇主程式ESCevent.c
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h> //gBS用
#include <Library/MemoryAllocationLib.h>

EFI_STATUS EFIAPI UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    // Initial
    EFI_STATUS Status = EFI_SUCCESS;
    ImageHandle=NULL;
    SystemTable=NULL;
    if (EFI_ERROR(Status))
        return Status;

    // 創建一個按鍵事件
    EFI_EVENT KeyEvent;
    Status = gBS->CreateEvent(
        EVT_TIMER | EVT_NOTIFY_WAIT,
        TPL_CALLBACK,
        (EFI_EVENT_NOTIFY)NULL,
        NULL,
        &KeyEvent
    );
    if (EFI_ERROR(Status)) {
        Print(L"Cannot create a key Event: %r\n", Status);
        return Status;
    }

    // 設置定時器,以便在按下ESC鍵後定期檢查
    Status = gBS->SetTimer(
        KeyEvent,
        TimerRelative,
        10000000  // 1000萬微秒(1秒)
    );
    if (EFI_ERROR(Status)) {
        Print(L"Cannot set timer: %r\n", Status);
        return Status;
    }

    // 迴圈,等待ESC鍵按下
    Print(L"按下ESC鍵以停止程式...\n");
    while(1){
        UINTN Index;
        EFI_INPUT_KEY Key;
        Status = gBS->WaitForEvent(1, &KeyEvent, &Index);
        if (!EFI_ERROR(Status)) {
            Status = gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
            if (!EFI_ERROR(Status) && Key.ScanCode == SCAN_ESC)
                break;  // 等ESC鍵被按下,退出迴圈
        }
    }

    // 釋放並退出
    gBS->CloseEvent(KeyEvent);
    return EFI_SUCCESS;
}


總結

今天是系列文中第一次介紹創建按鍵事件,利用4個:EFI_EVENTgBS->CreateEventgBS->WaitForEventgST->ConIn->ReadKeyStroke,後續我們還會繼續用到。我們明天見!


上一篇
【Day 18】自己寫UEFI顯示系統時間
下一篇
【Day 20】bootloader轉交控制權給kernel?ASM+UEFI寫kernel(上)
系列文
世界第一簡單的UEFI,實作打造自己的開機畫面31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言