UEFI 基础教程 (八) - EVENT 简单使用
一、 编写源代码
- 编写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
- 拷贝
C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\FV\OVMF.fd
到C:\qemu
;拷贝C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\X64\OvmfPkg\MyHelloWorldEvent\MyHelloWorldEvent\OUTPUT\MyHelloWorldEvent.efi
到 虚拟盘HDD_BOOT.img
- 执行
setup-qemu-x64.bat
| findstr MyHelloWorldEvent
, 然后在UEFI SHELL
中执行MyHelloWorldEvent.efi
,结果如下,
四、 小结
Events 是UEFI Service管理的另一个类型对像,可以提供一种异步机制来支持有限多任务,包括键盘、鼠标、定时器、Protocol等。本文利用使用Event部分API实现了对按键和定时器事件的监听,并做出简单处理。其中,CreateEvent用来生成事件,WaitForEvent用来阻塞等待事件被触发,CloseEvent用来销毁事件。