Step to UEFI (38) ----- SetTimer 设定定时器(下)

上一篇是直接输出一个计数器,我们还可以让他直接打印当前的时间,需要修改的代码不多,替换Timeout函数即可:

/**
  The callback function for the timer event used to get map.

  @param[in] Event    The event this function is registered to.
  @param[in] Context  The context registered to the event.
**/
VOID
EFIAPI
Timeout (
  IN EFI_EVENT      Event,
  IN VOID           *Context
  )
{
  EFI_STATUS  Status;
  EFI_TIME   ET;

  Status = gRT->GetTime(&ET, NULL);
  
  Print(L"%02d:%02d:%02d\r\n",ET.Hour,ET.Minute,ET.Second);
  return ;
}

 

settimes1

可以看到符合我们的期望。

接下来,我们之前的文章提到CLIB中也有时间相关的函数,我们尝试直接使用ctime函数。改动很小

/**
  The callback function for the timer event used to get map.

  @param[in] Event    The event this function is registered to.
  @param[in] Context  The context registered to the event.
**/
VOID
EFIAPI
Timeout (
  IN EFI_EVENT      Event,
  IN VOID           *Context
  )
{
  time_t t;

  time(&t);
 
  printf("%s\n",ctime(&t));
  
  return ;
}

 

但是会导致TPL错误

2b51136803959fa789bb6da4793609ad

b723a4c7633c0b1b141d33777dcc3942

错误原因不详。我请 HZZZ 帮忙看了一下,他发现如果我们使用默认的Shell_Full.efi就会出现问题,但是如果使用代码重新编译一个出来就不会有同样的问题(意思是:我们能够确定这是Shell本身的问题,但是没有会出现问题的Shell代码,因此无从得知Root Cause)。会出现下面的问题

timertest3

对于这个问题,HZZZ Debug的结果是:新编译出来的Shell不支持 SE2 这个Protocol.......

因此,如果想写一个兼容性强的程序,最好直接使用 UefiShellLib 提供的 ShellGetExecutionBreakFlag 函数。这个函数会自动判断当前有哪个Protocol,然后调用存在的功能。