S3/S4/S5 Long Run Test
- Why need it?
NB研发的工程中,需要跑很多的测试项目,其中long run S3/S4/S5就是非常重要的测试项目。而且对于测试结果非常看重,一般long run测试fail就没法出货。常规的测试方法就是10~20台机器测试S3/S4/S5 1000 cycle,如果fail率在万分之几就有可能要挂了。于是我就有了写一个long run S3/S4/S5测试程序的想法了。
- How to implement?
心动不如行动,Let’s go!经过几番查阅MSDN,S3/S4的功能已经有些眉目了,可是如何实现S5 wakeup呢?猛翻SDK&DDK,狂试API结果发现不行,好像没有相关的API能做到这件事。最后联系微软的FAE,他们的结论也是如此。既然常规做法不行,那么我就另辟蹊径。我知道BIOS Setup menu 有个选项可以设置RTC唤醒,只要机器还有电S5的状态下也可以唤醒机器。那么BIOS是怎么做的呢?我请教了BIOS 得知需要做两个动作:1.设置CMOS中的alarm time 2:将chipset RTC_EN bit置起然后进入S5。系统在alarm time到达时会产生wakeup event,Chipset会送power sequence系统就会开机。通过一个IO port driver,完成上述过程后我调用API ExitWindowsEx(EWX_SHUTDOWN|EWX_FORCE,0);关机,我等的头发都白了系统也没有唤醒L,到底什么地方出了问题呀?后来我用SE.exe模拟上述过程,结果发现RTC_EN被我修改过之后,过了一会居然又被改回原来的值了,看起来windows在幕后做了不少小动作哦J,这样一来这个方法就行不通了,那么该怎么办呢?答案就是使用EC_BIOS去做,只要有电EC就会运行,那么S5时EC仍然在工作,所以只需要EC在特定的条件下模拟一个开机动作即可。思路已经有了那么该如何实现呢?方法有两种:a.通过IO port driver 下81 cmd给66 port,然后将EC ram index和value送给62 port,这样就可以修改EC ram了,然后EC在S5时检查该EC ram值如果非0就倒数计时,时间到了就模拟一个开机动作,从而完成S5 wake up。b.同样是写EC ram不过使用不同的方法,我们可以在BIOS asl code里定制一个WMI ACPI device,并且在该device scope提供query/set EC ram的方法,并且提供一个WMI ACPI的driver,这样应用程序就可以方便的操纵EC ram了,而且一旦完成这只driver就可以完成非常多的增值部分,比如我们可以写一个程序读写EC ram中的battery info;或者我们可以写一个读取thermal info程序等等。
如下图1是程序的运行画面,该测试程序实现了S3/S4/S5的功能S3/S4在xp下面可以正常工作,而vista下无法唤醒L。下S3/S4是通下述代码实现的:
图 1
//hibernate and standby
int CAutoPowerOnShutdownDlg::SetPower(BOOL bSuspend,BOOL bForce)
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;