UEFI Common:Event 简单介绍和用法

    UEFI EVENT 的作用就是创建一个事件A,然后设定一个条件B,使得条件B满足的时候就执行这个事件A。条件B可以直接是

EFI_BOOT_SERVICES.SignalEvent()这种直接调用事件A,也可以用EFI_BOOT_SERVICES.SetTimer()设定一个时间段后执行事件A,也可以是EFI_BOOT_SERVICES.RegisterProtocolNotify()在某个Protocol interface被install或者reinstall的时候执行事件A。

    首先我们看如何去创建一个事件。创建事件有两个函数CreateEvent()和CreateEventEx()。CreateEvent()只创建一个事件。后CreateEventEx()创建一个事件列表,最常用的就是创建ReadyToBootEvent 在启动OS之前处理某些事情。

    我们先用个简单的例子来看看CreateEvent()的用法:

STATIC
VOID
EFIAPI
CHHEventTest (
  IN EFI_EVENT Event,
  IN VOID      *Context
  )
{
DEBUG ((EFI_D_INFO, "Charles EXE event ...\n"));
}
EFI_STATUS
EFIAPI
PlatformInit (
  IN  EFI_HANDLE        ImageHandle,
  IN  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_EVENT mCHHEvent;

  gBS->CreateEvent (
         EVT_TIMER | EVT_NOTIFY_SIGNAL,
         TPL_NOTIFY,
         CHHEventTest,
         NULL,//This used to pass parameter to CHHEventTest
         &mCHHEvent);
		 
  gBS->SetTimer (mCHHEvent, TimerRelative, 1 * 10 * 1000);
//  gBS->SetTimer (mCHHEvent, TimerPeriodic, 1 * 10 * 1000);

  DEBUG ((EFI_D_INFO, "Charles Event creat!\n"));
  }

    这里创建一个mCHHEvent 的事件,这个事件去调用了CHHEventTest这个函数,传递的参数为Null。这个mCHHEvent在1s之后被触发。关于TimerRelative这个参数,意思就是时间结束就触发事件如果是TimerPeriodic。那么这个mCHHEvent 会每隔1s被触发一次的循环下去。

    下面我们看CreateEventEx()的用法,我们创建两个Event:mCHHEvent和mCHHEvent2,公用一个GUID gCHHEventExtestGuid。示例如下:

STATIC
VOID
EFIAPI
CHHEventTest (
  IN EFI_EVENT Event,
  IN VOID      *Context
  )
{
DEBUG ((EFI_D_INFO, "Charles CHHEventTest ...\n"));
}

STATIC
VOID
EFIAPI
CHHEventTest2 (
  IN EFI_EVENT Event,
  IN VOID      *Context
  )
{
DEBUG ((EFI_D_INFO, "Charles CHHEventTest2 ...\n"));
}

EFI_STATUS
EFIAPI
PlatformInit (
  IN  EFI_HANDLE        ImageHandle,
  IN  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_EVENT mCHHEvent;
  EFI_EVENT mCHHEvent2;
  EFI_GUID gCHHEventExtestGuid  = { 0x0579257E, 0x1843, 0x45FB, { 0x83, 0x9D, 0x6B, 0x79, 0x09, 0x38, 0x29, 0xA9 } };
  
  gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  CHHEventTest,
                  NULL,
                  &gCHHEventExtestGuid,
                  &mCHHEvent
                  );
  gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  CHHEventTest2,
                  NULL,
                  &gCHHEventExtestGuid,
                  &mCHHEvent2
                  );
  DEBUG ((EFI_D_INFO, "Charles SignalEvent mCHHEvent  ...\n"));
  gBS->SignalEvent (mCHHEvent);
  DEBUG ((EFI_D_INFO, "Charles SignalEvent mCHHEvent2  ...\n"));
  gBS->SignalEvent (mCHHEvent2);
  }

    执行结果如下:

Charles SignalEvent mCHHEvent  ...
Charles CHHEventTest2 ...
Charles CHHEventTest ...
Charles SignalEvent mCHHEvent2  ...
Charles CHHEventTest2 ...
Charles CHHEventTest ...

    可以看出来,不管是Signal 同一个gCHHEventExtestGuid下面的任何一个Event,整个Event list 里面的Event都会被Signal。并且跟我们Signal的哪个Event 没有关系,同等TPL的后面的优先执行。那么我们改改不同TPL的看下,例如把mCHHEvent2的TPL降级为TPL_CALLBACK,执行结果如下:

Charles SignalEvent mCHHEvent  ...
Charles CHHEventTest ...
Charles CHHEventTest2 ...
Charles SignalEvent mCHHEvent2  ...
Charles CHHEventTest ...
Charles CHHEventTest2 ...
    这说明在同一个gCHHEventExtestGuid下面的不同TPL Event 执行顺序是按照TPL 高低顺序执行的,跟先后无关,同TPL 的Event后面的优先执行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值