但因為他提供了Timer中斷, 理論上就有機會做到異步操作以及分時多工。
實現這樣的目標可以透過 Boot Service提供的事件(Event)來達成。
首先使用 gBS->CreateEvent() 註冊一個 NotifyFunction (或稱CallBackFunction) 等待事件的發生或讓事件週期性的在背景執行。關閉Event須要呼叫 gBS->CloseEvent() 。因為是Boot Service所提供的,因此ExitBootServices()被系統呼叫後,BS的service/data都會消失。
先來看看Event的 typedef
typedef EFI_BOOTSERVICE EFI_STATUS (EFIAPI *EFI_CREATE_EVENT) ( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext, OUT EFI_EVENT * Event
);
|
比較常用的 Type 是 EVT_TIMER | EVT_NOTIFY_SIGNAL, 一旦所對應Event的Timer設定完成, 即執行到gBS->SetTimer(), 就會在背景周期性的執行所註冊的NotifyFunction。這就是一種分時多工的概念。
另一種也常用的 Type 是 EVT_TIMER | EVT_NOTIFY_WAIT, 做法是先透過gBS->SetTimer()給一個TimeOut時間,一旦所對應Event開始啟動等待, 即執行到gBS->WaitForEvent(), 就會不停的執行註冊的NotifyFunction並停在gBS->WaitForEvent()這支函式執行點,直到TimeOut
另外我們還可以使用改良版的Event函式EfiCreateProtocolNotifyEvent, 透過他我們可以指定某個Protocol被安裝後才啟動執行我們的NotifyFunction
另外我們還可以使用改良版的Event函式EfiCreateProtocolNotifyEvent, 透過他我們可以指定某個Protocol被安裝後才啟動執行我們的NotifyFunction
EFI_EVENT
EFIAPI
EfiCreateProtocolNotifyEvent(
IN EFI_GUID
*ProtocolGuid,
IN EFI_TPL
NotifyTpl,
IN EFI_EVENT_NOTIFY NotifyFunction,
IN
VOID
*NotifyContext, OPTIONAL
OUT
VOID
**Registration
)
{
EFI_STATUS Status;
EFI_EVENT Event;
//
//
Create the event
//
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
NotifyTpl,
NotifyFunction,
NotifyContext,
&Event
);
ASSERT_EFI_ERROR (Status);
//
//
Register for protocol notifactions on this event
//
Status = gBS->RegisterProtocolNotify (
ProtocolGuid,
Event,
Registration
);
ASSERT_EFI_ERROR (Status); //
//
Kick the event so we will perform an initial pass of
//
current installed drivers
//
// the library
will signal this event immediately once
gBS->SignalEvent (Event);
return Event;
}
|
<note 1> UEFI有提供多線程(Multi-Processor)來執行函式的library,請參考EFI_MP_SERVICES_PROTOCOL,用途是呼叫特定AP的或呼叫全部的AP來執行函式。
Martin 每次看你的文章都覺得收穫很多 希望能看到你更多分享
回覆刪除收穫很多很好
回覆刪除那你要準備轉行了嗎XDD