UEFI 基础教程 (九) - EVENT 简单使用

UEFI 基础教程 (八) - EVENT 简单使用

一、 编写源代码

  1. 编写UEFI Application
    代码C:\edkii\OvmfPkg\MyHelloWorldEvent\MyHelloWorldEvent.c,
EFI_STATUS MyHelloWorldEventEntry(
        IN EFI_HANDLE           ImageHandle,
        IN EFI_SYSTEM_TABLE     *SystemTable
        )
{
    EFI_STATUS Status;

    UINTN        Index=0;
    EFI_INPUT_KEY      Key;
    EFI_EVENT myEvents[2] = {0};
    

    Print (L"[MyHelloWorldEvent] MyHelloWorldEventEntry Start..\n");
    // 1. 生成事件
    // 生成按键事件
    myEvents[0] = gST->ConIn->WaitForKey;
     

    
    // 生成Timer事件
    Status = gBS->CreateEvent(EVT_TIMER , TPL_CALLBACK, (EFI_EVENT_NOTIFY)NULL, (VOID*)NULL, &myEvents[1]);
    if(EFI_ERROR(Status)){
      Print (L"[MyHelloWorldEvent] CreateEvent %r ...\n",Status);
      return Status;
    }
    
    Status = gBS->SetTimer(myEvents[1],TimerPeriodic , 100 * 1000 * 1000);//设置10秒定时
    if(EFI_ERROR(Status)){
      Print (L"[MyHelloWorldEvent] SetTimer %r ...\n",Status);
      return Status;
    }
    
    while (1){
        //2. 阻塞并等待事件被触发
        Status = gBS->WaitForEvent(2, myEvents, &Index);
        if(EFI_ERROR(Status)){
          Print (L"[MyHelloWorldEvent] WaitForEvent %r ...\n",Status);
          return Status;
        }
    
        if (Index == 0){
            // 读取按键键值并显示
            Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); 
            switch (Key.ScanCode){
              case SCAN_UP:
                Print (L"[MyHelloWorldEvent]  Key UP is Pressed..\n");
                break;
           
              case SCAN_DOWN:
                Print (L"[MyHelloWorldEvent]  Key Down is Pressed..\n");
                break;
              
              ...
                
              case SCAN_ESC:
                Print (L"[MyHelloWorldEvent]  Key ESC is Pressed..\n");
                goto End;
                
              default:
                Print (L"[MyHelloWorldEvent] Key %a is Pressed..\n",(CHAR8 *)&Key.UnicodeChar);
                break;
            }
        }else{
            Print (L"[MyHelloWorldEvent]  Timer event is trigered ..\n");
        }
    }
    
End:
    //销毁事件
    Status = gBS->CloseEvent(myEvents[0]);
    Status = gBS->CloseEvent(myEvents[1]);
      
    Print (L"[MyHelloWorldEvent] MyHelloWorldEventEntry End..\n");
    return Status;
}

二、 编译生成EFI文件

运行edksetup.bat编译整个OvmfPkg Package

三、 运行 UEFI APP MyHelloWorldEvent.efi

  1. 拷贝 C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\FV\OVMF.fdC:\qemu;拷贝C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\X64\OvmfPkg\MyHelloWorldEvent\MyHelloWorldEvent\OUTPUT\MyHelloWorldEvent.efi 到 虚拟盘HDD_BOOT.img
  2. 执行setup-qemu-x64.bat | findstr MyHelloWorldEvent , 然后在UEFI SHELL 中执行 MyHelloWorldEvent.efi,结果如下,
    UEFI 基础教程 (九) - EVENT 简单使用_第1张图片

四、 小结

Events 是UEFI Service管理的另一个类型对像,可以提供一种异步机制来支持有限多任务,包括键盘、鼠标、定时器、Protocol等。本文利用使用Event部分API实现了对按键和定时器事件的监听,并做出简单处理。其中,CreateEvent用来生成事件,WaitForEvent用来阻塞等待事件被触发,CloseEvent用来销毁事件。

你可能感兴趣的:(15_固件开发)