用的是读取IO端口70、71显示bios时间。先贴个完整的代码:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/IoLib.h>
#include <Library/UefiBootServicesTableLib.h>
#define CMOS_INDEX 0x70
#define CMOS_DATA 0x71
EFI_STATUS EFIAPI UefiMain(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable){
EFI_STATUS Status;
UINTN INDEX = 0,temp = 0;
EFI_EVENT event;
Status = gBS->CreateEvent(EVT_TIMER,TPL_APPLICATION,(EFI_EVENT_NOTIFY)NULL,(VOID *)NULL,&event);
Status = gBS->SetTimer(event,TimerPeriodic,11000*1000);
UINT8 second = 0;
UINT8 minute = 0;
UINT8 hour = 0;
UINT8 weekday = 0;
UINT8 date = 0;
UINT8 month = 0;
UINT8 year = 0;
Print(L"Start Hello, world quq!\r\n");
Print(L"End Hello, world qaq!\r\n");
while(temp < 10){
IoWrite8(CMOS_INDEX,0x00);
second = IoRead8(CMOS_DATA);
IoWrite8(CMOS_INDEX,0x02);
minute = IoRead8(CMOS_DATA);
IoWrite8(CMOS_INDEX,0x04);
hour = IoRead8(CMOS_DATA);
IoWrite8(CMOS_INDEX,0x06);
weekday = IoRead8(CMOS_DATA);
IoWrite8(CMOS_INDEX,0x07);
date = IoRead8(CMOS_DATA);
IoWrite8(CMOS_INDEX,0x08);
month = IoRead8(CMOS_DATA);
IoWrite8(CMOS_INDEX,0x09);
year = IoRead8(CMOS_DATA);
Print(L"20%02x/%02x/%02x %02x %02x:%02x:%02x\n",year,month,date,weekday,hour,minute,second);
Status = gBS->WaitForEvent(1,&event,&INDEX);
temp++;
}
gBS->CloseEvent(event);
return EFI_SUCCESS;
}
EVENT需要用到gBS结构体,需要include下面这个库,并且在inf文件的[LibraryClasses] 块中声明
#include <Library/UefiBootServicesTableLib.h>
首先是CreateEvent,有5个参数:
Status = gBS->CreateEvent(EVT_TIMER,TPL_APPLICATION,(EFI_EVENT_NOTIFY)NULL,(VOID *)NULL,&event);
第一个是事件类型,有如下几种常见的:
本文用到的是EVT_TIMER定时器事件。
第二个参数是优先级:
数字越大的优先级越高。
第三和第四个参数是触发事件回调函数的,第三个是函数地址,第四个是函数参数。这里可以不用,直接赋值为NULL。
第五个是事件返回的句柄,可以用这个来指向CreateEvent创建的事件。
创建好后就可以set定时器的参数了,当set完之后这个定时器就启动了。
Status = gBS->SetTimer(event,TimerPeriodic,10*1000*1000);
第一个参数是刚才CreateEvent返回的句柄。
第二个参数是定时器类别:
我们这里设置的是重复型的,当不需要使用了之后只需要
Status = gBS->SetTimer(event,TimerCancel,10*1000*1000);
参数改成TimerCancel就可以disable这个定时器。
第三个参数10*1000*1000我运行出来是1s,我看网上这个时间有些版本是不一样的,若不对可自行更改。
Status = gBS->WaitForEvent(1,&event,&INDEX);
然后这个函数就是相当于Delay了,每调用一次会在这里阻塞1s,1s后再往下执行。
第二个参数是一个数组的首地址,第一个参数是数组的个数,这个数组可以存放很多个事件,当阻塞的时候任意一个数组内的事件被触发后才会完成返回。INDEX内会保存触发的数组事件下标。
我们这里只有一个定时器事件,所以调用这个Wait函数后只会等待1s就触发,INDEX返回0,这个函数执行结束。
这是执行结果: