EDK2 UEFI中使用event定时器实现延时delay 1s

  用的是读取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,这个函数执行结束。

这是执行结果:

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值