event 情景分析

在进bios setup 之前,我们可以在屏幕上显示“Entering BIOS Setup

BIOS 以一秒为步长 周期性的打印到屏幕上。

这个就是用event 来实现的。

相关代码如下:

  //
  // Create a timer to indicate "Entering Setup".
  //

  IndicatorMessage = NULL;
  IndicatorMessage = HiiGetString (mStringHiiHandle, STRING_TOKEN (STRING_SYSTEM_BIOS_SETUP_ENTERING_MSG), NULL);

  DPRINTF (" maxwell maxwell start show IndicatorMessage = %s\n", IndicatorMessage);

  gBS->CreateEvent (
         EVT_TIMER | EVT_NOTIFY_SIGNAL,
         TPL_NOTIFY,
         IndicatorMsg,
         (VOID*)IndicatorMessage,
         &TimerEvent);
  gBS->SetTimer (TimerEvent, TimerPeriodic, 1 * 1000 * 1000);

函数gBS->CreateEvent  创建了TimerEvent。  然后将TimerEvent 传给 gBS->SetTimer, 注意SetTimer 的第二个参数TimerPeriodic, 表明这个事情将会被周期性的触发。

那接下来,引出一个问题, 上面事件每一秒跑一次, 什么时候截止呢?

顺着代码往下看,我们看到了如下三行代码:

  //
  // Stop the timer.
  //

  gBS->SetTimer (TimerEvent, TimerCancel, 0);
  gBS->CloseEvent (TimerEvent);
  TimerEvent = NULL;
  }  

第一行, 给SetTimer 传入TimerCancel, 表明这个事件会被取消

第二行CloseEvent , 将event 从链表上摘除,后续 谁也不能用它了。

第三行 指针 指向空,防止野指针。

接下来,对CreateEvent 和SetTimer  进行详细分析

/**
  Sets the type of timer and the trigger time for a timer event.

  @param  UserEvent              The timer event that is to be signaled at the
                                 specified time
  @param  Type                   The type of time that is specified in
                                 TriggerTime
  @param  TriggerTime            The number of 100ns units until the timer
                                 expires

  @retval EFI_SUCCESS            The event has been set to be signaled at the
                                 requested time
  @retval EFI_INVALID_PARAMETER  Event or Type is not valid

**/
EFI_STATUS
EFIAPI
CoreSetTimer (
  IN EFI_EVENT            UserEvent,
  IN EFI_TIMER_DELAY      Type,
  IN UINT64               TriggerTime
  )
{
  IEVENT      *Event;

  Event = UserEvent;

  if (Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Event->Signature != EVENT_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  if ((UINT32)Type > TimerRelative  || (Event->Type & EVT_TIMER) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  CoreAcquireLock (&mEfiTimerLock);

  //
  // If the timer is queued to the timer database, remove it
  //
  if (Event->Timer.Link.ForwardLink != NULL) {
    RemoveEntryList (&Event->Timer.Link);
    Event->Timer.Link.ForwardLink = NULL;
  }

  Event->Timer.TriggerTime = 0;
  Event->Timer.Period = 0;

  if (Type != TimerCancel) {

    if (Type == TimerPeriodic) {
      if (TriggerTime == 0) {
        gTimer->GetTimerPeriod (gTimer, &TriggerTime);
      }
      Event->Timer.Period = TriggerTime;
    }

    Event->Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;
    CoreInsertEventTimer (Event);

    if (TriggerTime == 0) {
      CoreSignalEvent (mEfiCheckTimerEvent);
    }
  }

  CoreReleaseLock (&mEfiTimerLock);

  return EFI_SUCCESS;
}

如果参数不是TimerCancel , 将Event 插入链表里面 CoreInsertEventTimer (Event);  如果时间为0. 直接触发CoreSignalEvent (mEfiCheckTimerEvent);

/**
  Initializes timer support.

**/
VOID
CoreInitializeTimer (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = CoreCreateEventInternal (
             EVT_NOTIFY_SIGNAL,
             TPL_HIGH_LEVEL - 1,
             CoreCheckTimers,
             NULL,
             NULL,
             &mEfiCheckTimerEvent
             );
  ASSERT_EFI_ERROR (Status);
}

CoreCheckTimers 

函数实现如下:

/**
  Checks the sorted timer list against the current system time.
  Signals any expired event timer.

  @param  CheckEvent             Not used
  @param  Context                Not used

**/
VOID
EFIAPI
CoreCheckTimers (
  IN EFI_EVENT            CheckEvent,
  IN VOID                 *Context
  )
{
  UINT64                  SystemTime;
  IEVENT                  *Event;

  //
  // Check the timer database for expired timers
  //
  CoreAcquireLock (&mEfiTimerLock);
  SystemTime = CoreCurrentSystemTime ();

  while (!IsListEmpty (&mEfiTimerList)) {
    Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE);

    //
    // If this timer is not expired, then we're done
    //
    if (Event->Timer.TriggerTime > SystemTime) {
      break;
    }

    //
    // Remove this timer from the timer queue
    //

    RemoveEntryList (&Event->Timer.Link);
    Event->Timer.Link.ForwardLink = NULL;

    //
    // Signal it
    //
    CoreSignalEvent (Event);

    //
    // If this is a periodic timer, set it
    //
    if (Event->Timer.Period != 0) {
      //
      // Compute the timers new trigger time
      //
      Event->Timer.TriggerTime = Event->Timer.TriggerTime + Event->Timer.Period;

      //
      // If that's before now, then reset the timer to start from now
      //
      if (Event->Timer.TriggerTime <= SystemTime) {
        Event->Timer.TriggerTime = SystemTime;
        CoreSignalEvent (mEfiCheckTimerEvent);
      }

      //
      // Add the timer
      //
      CoreInsertEventTimer (Event);
    }
  }

  CoreReleaseLock (&mEfiTimerLock);
}

将每个时间到了的事件,触发,即跑起来。

猜你喜欢

转载自blog.csdn.net/robinsongsog/article/details/106489842
今日推荐