请教关于系统自动进入深度休眠的问题

wangxin_801115 2009-02-13 10:12:02
加精
我的系统是WINCE4的

现在的问题是这样的:在CE下“控制面板”->“电源”->“方案”下分三种休眠:用户休眠(useridle)、系统休眠(systemidle)、和深度休眠(也叫挂起或者CPU休眠)
我们设计的流程是可以设置“用户休眠”然后进入“系统休眠”,但是绝不让进入“深度休眠”
所以在D:\WINCE420\PUBLIC\WCESHELLFE\OAK\CTLPNL\CPLMAIN下的power.cpp中将设置的选项去掉,在注册表中设置为0(从不)
而“深度休眠”只是当“按我们设置的开关键”和“电池电量过低”的时候才会进入的,方法是调用系统函数GwesPowerOffSystem();
可是现在当系统启动后,没有人动它,他会先进入“用户休眠”然后进入“系统休眠”,然后偶尔会自己进入到“深度休眠”!
我已经在电池驱动中调用GwesPowerOffSystem();之前加了打印信息,可是不是这两个地方出现的问题!

我的电源管理驱动是WINCE4.2下的,也是分层的,上层在D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\BATTDRVR\battdrvr.c中,可是我觉得并不是电源管理的问题
因为电源管理驱动中仅仅那两个地方涉及到调用系统函数GwesPowerOffSystem();是跟深度休眠有关系的

我的深度休眠是在D:\WINCE420\PLATFORM\MCORE\kernel\HAL\ARM下的pmgr.c中设置的:
pSlpParams->PWER = 0x00000000u; // PMGR_PWER_DFLT; // Wake for RTC alarm or GPIO1
pSlpParams->PRER = 0u;// PMGR_PRER_DFLT;
pSlpParams->PFER = 0u;// PMGR_PFER_DFLT;
pSlpParams->PKWR = 0x100u; // PMGR_PKWR_DFLT;
所以深度休眠会调用pmgr.c中的函数OEMPowerOff,使系统休眠,
但是不知道哪里还会调用OEMPowerOff这个函数,或者是满足什么条件调用OEMPowerOff这个函数,或者调用了GwesPowerOffSystem这个函数,或者是调用别的函数造成的深度休眠
总之,莫名其妙的进入了深度休眠!
请教个位高手:关于这个问题还有可能出现在什么地方,有可能是什么情况造成的呢??
谢谢啦各位!!!
...全文
1563 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
delphiers 2009-02-19
  • 打赏
  • 举报
回复
好好来了解下!
RMB_Exist 2009-02-19
  • 打赏
  • 举报
回复
学习了
wangxin_801115 2009-02-19
  • 打赏
  • 举报
回复
找到问题了:
系统执行了public中PM下的电源管理
在D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\PM\PDD\DEFAULT\platform.cpp下
PlatformUpdateSystemPowerState函数中
case Timeout:
DEBUGCHK(gdwStateTimeLeft != INFINITE);
if(dwElapsedTime >= gdwStateTimeLeft) {
RETAILMSG(1, (TEXT("Stepfffffffffffffffffffff!!!!!!!\r\n")));
asNew = Suspend;
之后,让系统进入了深度休眠
但是我已经在控制面板中深度休眠设置成了“从不”,这样还会进入深度休眠!!!
zalu 2009-02-19
  • 打赏
  • 举报
回复
学习
帮你顶
Yao_2002 2009-02-16
  • 打赏
  • 举报
回复
学习
wangxin_801115 2009-02-15
  • 打赏
  • 举报
回复
在配置好注册表相关的选项的情况下,有驱动主动提交及修改系统电源状态,导致非预设的自动进入休眠,或者希望进入休眠而无法休眠。这两种情况都碰到过。

一般都是在已经成熟的平台(bsp)中加入新模块新驱动,导致这样的。

我的电源管理驱动就是后加的

CE下的电源管理我没有用,但是我发现我的平台上已经加了电源管理的组件了,编译后生成了一个PM.DLL

我觉得可能是这个PM发生了作用,导致了不正常的深度休眠!
wangxin_801115 2009-02-15
  • 打赏
  • 举报
回复
重大发现:
在我的工程文件中有pm.dll这个文件
搜这个相关的DEF文件
发现在 D:\WINCE420\PB_WorkSpace\MCPLAT\WINCE420\MCORE\cesysgen\oak\inc\pm.def中定义了

LIBRARY PM

EXPORTS
PmNotify
PmGetSystemPowerState
PmSetSystemPowerState
PmSetPowerRequirement
PmReleasePowerRequirement
PmRequestPowerNotifications
PmStopPowerNotifications
PmDevicePowerNotify
PmRegisterPowerRelationship
PmReleasePowerRelationship
PmSetDevicePower
PmGetDevicePower
PmPowerHandler
PmInit
搜这几个函数发现是在D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\PM中
说明我用到了系统提供的电源管理,可是我没有修改过这个代码,
我想应该是用到那个D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\PM\PDD下的DEFAULT文件夹中的内容了
如果这样的话,我想应该是系统运行了它自己的这套电源管理,跟我的大概有什么冲突了吧
估计在调用OEMPowerOff这个函数处打印点信息就可以找到了
希望是这样
但是如果我的猜测成立的话
我在注册表中已经设置了
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\Timeouts]
"ACSuspend"=dword:00000000
"ACSystemIdle"=dword:0000012c
"ACUserIdle"=dword:0000003c
"BattSuspend"=dword:00000000
"BattSystemIdle"=dword:000000b4
"BattUserIdle"=dword:00000000

Ricky_hu 2009-02-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wangxin_801115 的回复:]
重大发现:
在我的工程文件中有pm.dll这个文件
搜这个相关的DEF文件
发现在    D:\WINCE420\PB_WorkSpace\MCPLAT\WINCE420\MCORE\cesysgen\oak\inc\pm.def中定义了

LIBRARY    PM

EXPORTS
PmNotify
PmGetSystemPowerState
PmSetSystemPowerState
PmSetPowerRequirement
PmReleasePowerRequirement
PmRequestPowerNotifications
PmStopPowerNotifications
PmDevicePowerNotify
PmRegisterPowerRelationship
P…
[/Quote]

应该就是后台的PM驱动在起作用,而你没有修改。
lz可以把这个路径,D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\PM下的内容copy到bsp的drivers目录下面,然后把它编译成debug版本的pm.dll驱动,这样的话所有PM的信息都能够打印出来
shuiyan 2009-02-15
  • 打赏
  • 举报
回复
这部分我真没详细做过,帮不上太多忙了。

不管对哪个平台,电源管理都是极其复杂和重要的。

在配置好注册表相关的选项的情况下,有驱动主动提交及修改系统电源状态,导致非预设的自动进入休眠,或者希望进入休眠而无法休眠。这两种情况都碰到过。

一般都是在已经成熟的平台(bsp)中加入新模块新驱动,导致这样的。
hahagoodhaha 2009-02-15
  • 打赏
  • 举报
回复
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\Timeouts]
"ACUserIdle"=dword:B4 ;3c ; in seconds
"ACSystemIdle"=dword:0 ; in seconds
"ACSuspend"=dword:0 ; in seconds
"BattUserIdle"=dword:B4 ;3c ; in seconds
"BattSystemIdle"=dword:0 ; in seconds
"BattSuspend"=dword:0 ; in seconds
首先确定"BattSystemIdle"=dword:0 的值是 0,然后确定Control Panel中这个值没有被设置成其它值,这两个确定都为0后,如果还是进入Suspend,请search 你的drivers and Apps中是否有call SetSystemPowerState(POWER_STATE_SUSPEND)
bestboy1 2009-02-15
  • 打赏
  • 举报
回复
关注。
shuiyan 2009-02-15
  • 打赏
  • 举报
回复
pm还是有用的。查查别的驱动。如果可能,可以先把别的驱动都先删了,只保留lcd驱动,看看能不能有正确的电源状态。
wangxin_801115 2009-02-14
  • 打赏
  • 举报
回复
昨天我找到一个PowerOffSystem函数。是在电源管理的上层中:D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\BATTDRVR\battdrvr.c
不知道这个函数是有什么作用
还有在:D:\WINCE420\PRIVATE\WINCEOS\COREOS\NK\KERNEL\kwin32.c下有调用了OEMPowerOff函数
不知道PRIVATE文件夹中的文件是否能被编译和执行到?
gsymichael 2009-02-14
  • 打赏
  • 举报
回复
关注。
wangxin_801115 2009-02-14
  • 打赏
  • 举报
回复
TO Ricky_hu:
“这个路径的代码D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\BATTDRVR\battdrvr.c是电池驱动的吧,难道wince4.2的电源管理不是在PM中而是在battery中?? ”

您这么一说我突然有种眩晕的感觉!

我这个只是单纯的电池驱动,里面涉及到“深度休眠”

至于电源管理我只做了:
DWORD WINAPI IdleListenThread(LPVOID lpParameter)
{
DWORD dwWaitResult;
HANDLE hEventIdleListen = (HANDLE)lpParameter;
POWER_STATUS status;

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
while (1)
{
dwWaitResult = WaitForSingleObject(hEventIdleListen, g_dwTimeWaitfor);

if ( dwWaitResult == WAIT_OBJECT_0 )
{
if (g_LastPowerStatus == pstatus_busy)
{
continue;
}

OnIdleWakeup(g_LastPowerStatus);
if ( IsACOnline() )
{
g_dwTimeWaitfor = RegReadStatusTimeout(pstatus_acuseridle);
g_CurPowerStatus = pstatus_acuseridle;
}
else
{
g_dwTimeWaitfor = RegReadStatusTimeout(pstatus_battuseridle);
g_CurPowerStatus = pstatus_battuseridle;
}
g_LastPowerStatus = pstatus_busy;
continue;
} // end if

status = g_CurPowerStatus;

switch (g_CurPowerStatus)
{
case pstatus_acuseridle:
case pstatus_battuseridle:
OnUseridle(g_LastPowerStatus);
if ( IsACOnline() )
{
g_dwTimeWaitfor = RegReadStatusTimeout(pstatus_acsystemidle);
g_CurPowerStatus = pstatus_acsystemidle;
}
else
{
g_dwTimeWaitfor = RegReadStatusTimeout(pstatus_battsystemidle);
g_CurPowerStatus = pstatus_battsystemidle;
}
break;
case pstatus_acsystemidle:
case pstatus_battsystemidle:
OnSystemidle(g_LastPowerStatus);
g_dwTimeWaitfor = INFINITE;
g_CurPowerStatus = pstatus_busy;
break;
default:
if (g_LastPowerStatus != pstatus_busy)
{
OnIdleWakeup(g_LastPowerStatus);
}
if ( IsACOnline() )
{
g_dwTimeWaitfor = RegReadStatusTimeout(pstatus_acuseridle);
g_CurPowerStatus = pstatus_acuseridle;
}
else
{
g_dwTimeWaitfor = RegReadStatusTimeout(pstatus_battuseridle);
g_CurPowerStatus = pstatus_battuseridle;
}
break;
} // end switch
g_LastPowerStatus = status;
} // end while
return 0;
}
不知道电源管理还涉及到哪些内容
wangxin_801115 2009-02-14
  • 打赏
  • 举报
回复
TO Ricky_hu:
1、我的注册表:
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\Timeouts]
"ACSuspend"=dword:00000000
"ACSystemIdle"=dword:0000012c
"ACUserIdle"=dword:0000003c
"BattSuspend"=dword:00000000
"BattSystemIdle"=dword:000000b4
"BattUserIdle"=dword:00000000
ENDIF ;BSP_NOSQLCE30

Ricky_hu 2009-02-14
  • 打赏
  • 举报
回复
......可是现在当系统启动后,没有人动它,他会先进入“用户休眠”然后进入“系统休眠”,然后偶尔会自己进入到“深度休眠”! ........

这应该是系统的电源管理起作用了。lz是设置了下面的注册表红色部分来禁止进入深度休眠吗?

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\Timeouts]
"ACUserIdle"=dword:B4 ;3c ; in seconds
"ACSystemIdle"=dword:0 ; in seconds
"ACSuspend"=dword:0 ; in seconds
"BattUserIdle"=dword:B4 ;3c ; in seconds
"BattSystemIdle"=dword:0 ; in seconds
"BattSuspend"=dword:0 ; in seconds
如果是这样的话,应该不会自动进入深度休眠状态的。

另,这个路径的代码D:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\BATTDRVR\battdrvr.c是电池驱动的吧,难道wince4.2的电源管理不是在PM中而是在battery中??
wangxin_801115 2009-02-13
  • 打赏
  • 举报
回复
上面有个地方写错了:
D:\WINCE420\PLATFORM\MCORE\kernel\HAL\ARM下的pmgr.c中设置的:
pSlpParams->PWER = 0x00000000u; // PMGR_PWER_DFLT; // Wake for RTC alarm or GPIO1
pSlpParams->PRER = 0u;// PMGR_PRER_DFLT;
pSlpParams->PFER = 0u;// PMGR_PFER_DFLT;
pSlpParams->PKWR = 0x100u; // PMGR_PKWR_DFLT; 这个是设置唤醒,不是休眠

D:\WINCE420\PLATFORM\MCORE\kernel\HAL\ARM下的pmgr.c中的OEMPowerOff才是休眠:
void OEMPowerOff (void)
{
pMemc = (volatile PMEMC )MEMC_BASE_U_VIRTUAL;
pPmSleepData = (volatile P_PM_SLEEP_DATA_T)SLEEP_SAVE_U_VIRTUAL;
pPwrMgrRegs = (volatile P_XLLP_PWRMGR_T)XLLP_U_V_PWRMGR_BASE;
pPmgrSleepParams = &pPmSleepData->sleepParameters;

NKDbgPrintfW(TEXT("OEMPowerOff\r\n"));
msWait(2000);
XllpPmEnterSleep (pPmgrSleepParams);
} // OEMPowerOff()
每次休眠(不论正常或者不正常)都会打印OEMPowerOff这条信息
XllpPmEnterSleep (pPmgrSleepParams);是真正使系统休眠的函数,
因为先打印信息,所以并不是因为系统某处改变了寄存器状态导致的不正常休眠
而应该是系统不知道在什么情况下就会调用void OEMPowerOff (void)这个函数,或者GwesPowerOffSystem这个函数(GwesPowerOffSystem中应该是调用OEMPowerOff 函数)!

19,503

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧