|
|
|
@ -44,7 +44,7 @@
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(LOSCFG_KERNEL_RUNSTOP) || defined(LOSCFG_KERNEL_DEEPSLEEP)
|
|
|
|
|
/* Is system is up from the memory image, then this flag should be 1; else 0 */
|
|
|
|
|
/* 如果系统是从内存映像中启动的,则该标志应为1;否则为0。*/
|
|
|
|
|
#ifdef LOSCFG_AARCH64
|
|
|
|
|
__attribute__((section(".data"))) INT64 g_resumeFromImg = LOS_COLD_RESET;
|
|
|
|
|
__attribute__((section(".data"))) STATIC INT64 g_otherCoreResume = 0;
|
|
|
|
@ -55,8 +55,8 @@ __attribute__((section(".data"))) INT32 g_otherCoreResume = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_AARCH64
|
|
|
|
|
/*
|
|
|
|
|
* 16: The number of aligned memory,
|
|
|
|
|
* 34: The number of task context registers(X0~X30, SP, DAIF, NZCV)
|
|
|
|
|
* 16: 对齐内存的数量,
|
|
|
|
|
* 34: 任务上下文寄存器的数量,指寄存器的集合(X0~X30, SP, DAIF, NZCV)
|
|
|
|
|
*/
|
|
|
|
|
LITE_OS_SEC_DATA_MINOR __attribute__((aligned(16))) UINT64 g_saveSRContext[34];
|
|
|
|
|
/* 3: The number of available universal registers(X0, X1, X2) temporarily saved */
|
|
|
|
@ -161,24 +161,24 @@ STATIC PowerMgrRunOps g_pmRunOps = {
|
|
|
|
|
.postConfig = OsPostConfigDefault,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLightSleepDefault(VOID)
|
|
|
|
|
STATIC VOID OsLightSleepDefault(VOID)/*轻量级睡眠函数,执行wfi指令,让处理器进入睡眠状态*/
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
wfi();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick)
|
|
|
|
|
STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick)/*设置唤醒定时器,默认实现为空函数*/
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID)
|
|
|
|
|
STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID)/*撤销唤醒定时器,默认实现返回0*/
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsGetSleepTimeDefault(VOID)
|
|
|
|
|
STATIC UINT32 OsGetSleepTimeDefault(VOID)/*获取当前任务休眠时间*/
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_TICKLESS
|
|
|
|
|
return OsSleepTicksGet();
|
|
|
|
@ -187,12 +187,12 @@ STATIC UINT32 OsGetSleepTimeDefault(VOID)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)
|
|
|
|
|
STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)/*选择合适的休眠模式*/
|
|
|
|
|
{
|
|
|
|
|
if (sleepTicks < g_pmMgr.minSleepTicks) {
|
|
|
|
|
return LOS_INTERMIT_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*默认实现根据休眠时间和当前系统状态选择轻量级睡眠或者深度睡眠模式*/
|
|
|
|
|
if (g_pmMgr.deepSleepOps != NULL && sleepTicks >= g_pmMgr.minDeepSleepTicks &&
|
|
|
|
|
g_pmRunOps.getDeepSleepVoteCount() == 0) {
|
|
|
|
|
return LOS_INTERMIT_DEEP_SLEEP;
|
|
|
|
@ -201,73 +201,73 @@ STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)
|
|
|
|
|
return LOS_INTERMIT_LIGHT_SLEEP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsChangeFreqDefault(UINT8 freq)
|
|
|
|
|
STATIC VOID OsChangeFreqDefault(UINT8 freq)/*改变处理器频率*/
|
|
|
|
|
{
|
|
|
|
|
(VOID)freq;
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsEnterDeepSleepDefault(VOID)
|
|
|
|
|
STATIC VOID OsEnterDeepSleepDefault(VOID)// 进入深度睡眠模式函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
wfi();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsPreConfigDefault(VOID)
|
|
|
|
|
STATIC UINT32 OsPreConfigDefault(VOID)//电源管理模块预配置函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsPostConfigDefault(VOID)
|
|
|
|
|
STATIC VOID OsPostConfigDefault(VOID)//电源管理模块后配置函数
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_DEEPSLEEP
|
|
|
|
|
|
|
|
|
|
STATIC BOOL OsCouldDeepSleepDefault(VOID)
|
|
|
|
|
STATIC BOOL OsCouldDeepSleepDefault(VOID)// 判断是否可以进入深度睡眠模式
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC BOOL OsSuspendPreConfigDefault(VOID)
|
|
|
|
|
STATIC BOOL OsSuspendPreConfigDefault(VOID)// 休眠前的预配置函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsSuspendDeviceDefault(VOID)
|
|
|
|
|
STATIC VOID OsSuspendDeviceDefault(VOID)//休眠时设备挂起函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsRollBackDefault(VOID)
|
|
|
|
|
STATIC VOID OsRollBackDefault(VOID)//唤醒后的回滚函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsResumeDeviceDefault(VOID)
|
|
|
|
|
STATIC VOID OsResumeDeviceDefault(VOID)//唤醒后的设备恢复函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsResumePostConfigDefault(VOID)
|
|
|
|
|
STATIC VOID OsResumePostConfigDefault(VOID)//唤醒后电源管理模块后配置函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsSystemWakeupDefault(VOID)
|
|
|
|
|
STATIC VOID OsSystemWakeupDefault(VOID)//系统唤醒函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsResumeCallBackDefault(VOID)
|
|
|
|
|
STATIC VOID OsResumeCallBackDefault(VOID)//唤醒后回调函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsOtherCoreResumeDefault(VOID)
|
|
|
|
|
STATIC VOID OsOtherCoreResumeDefault(VOID)//其他核心唤醒函数
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
@ -275,18 +275,18 @@ STATIC VOID OsOtherCoreResumeDefault(VOID)
|
|
|
|
|
STATIC VOID OsDeepSleepResume(VOID);
|
|
|
|
|
|
|
|
|
|
STATIC PowerMgrDeepSleepOps g_deepSleepOps = {
|
|
|
|
|
.couldDeepSleep = OsCouldDeepSleepDefault,
|
|
|
|
|
.systemWakeup = OsSystemWakeupDefault,
|
|
|
|
|
.suspendPreConfig = OsSuspendPreConfigDefault,
|
|
|
|
|
.suspendDevice = OsSuspendDeviceDefault,
|
|
|
|
|
.rollback = OsRollBackDefault,
|
|
|
|
|
.resumeDevice = OsResumeDeviceDefault,
|
|
|
|
|
.resumePostConfig = OsResumePostConfigDefault,
|
|
|
|
|
.resumeCallBack = OsResumeCallBackDefault,
|
|
|
|
|
.otherCoreResume = OsOtherCoreResumeDefault
|
|
|
|
|
.couldDeepSleep = OsCouldDeepSleepDefault, //判断是否可以进入深度睡眠模式的函数指针
|
|
|
|
|
.systemWakeup = OsSystemWakeupDefault,//唤醒函数的函数指针
|
|
|
|
|
.suspendPreConfig = OsSuspendPreConfigDefault,//修面前的预配置函数的函数指针
|
|
|
|
|
.suspendDevice = OsSuspendDeviceDefault,//设备挂起函数的函数指针
|
|
|
|
|
.rollback = OsRollBackDefault,//唤醒后的回滚函数的函数指针
|
|
|
|
|
.resumeDevice = OsResumeDeviceDefault,//设备回复函数的函数指针
|
|
|
|
|
.resumePostConfig = OsResumePostConfigDefault,//唤醒后电源管理模块后配置函数的函数指针
|
|
|
|
|
.resumeCallBack = OsResumeCallBackDefault,//唤醒后回调函数的函数指针
|
|
|
|
|
.otherCoreResume = OsOtherCoreResumeDefault//其他核心唤醒函数的函数指针
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)
|
|
|
|
|
STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)//用于更新系统始终,根据休眠时间调整系统时钟
|
|
|
|
|
{
|
|
|
|
|
UINT32 cpuid = ArchCurrCpuid();
|
|
|
|
|
if (sleepTicks > g_pmMgr.sleepTime[cpuid]) {
|
|
|
|
@ -297,7 +297,7 @@ STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)
|
|
|
|
|
OsSysTimeUpdate(sleepTicks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsDeepSleepResume(VOID)
|
|
|
|
|
STATIC VOID OsDeepSleepResume(VOID)//深度睡眠唤醒后的处理函数
|
|
|
|
|
{
|
|
|
|
|
DEEPOPS_CALL_FUNC_VOID(resumeFromReset);
|
|
|
|
|
LOS_AtomicSet(&g_pmMgr.resumeSleepCores, OS_MP_CPU_ALL);
|
|
|
|
@ -305,30 +305,32 @@ STATIC VOID OsDeepSleepResume(VOID)
|
|
|
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
|
|
|
OsSetCpuCycle(0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//恢复设置,恢复其他核心进程
|
|
|
|
|
#if (LOSCFG_KERNEL_SMP == YES)
|
|
|
|
|
release_secondary_cores();
|
|
|
|
|
#endif
|
|
|
|
|
OsSRRestoreRegister();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)
|
|
|
|
|
STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)//用于主核心进入深度睡眠
|
|
|
|
|
{
|
|
|
|
|
//挂起预配置
|
|
|
|
|
LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1);
|
|
|
|
|
g_deepSleepOps.suspendPreConfig();
|
|
|
|
|
|
|
|
|
|
//是否可以进入神对睡眠判断
|
|
|
|
|
if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM && g_deepSleepOps.couldDeepSleep()) {
|
|
|
|
|
g_deepSleepOps.suspendDevice();
|
|
|
|
|
g_pmRunOps.setWakeUpTimer(g_pmMgr.sleepTime[0]);
|
|
|
|
|
g_resumeFromImg = LOS_COLD_RESET;
|
|
|
|
|
OsSRSaveRegister();
|
|
|
|
|
|
|
|
|
|
//进入深度睡眠,进行回滚操作,保存上下文
|
|
|
|
|
if (g_resumeFromImg == LOS_COLD_RESET) {
|
|
|
|
|
g_resumeFromImg = LOS_DEEP_SLEEP_RESET;
|
|
|
|
|
CALL_RUN_OPS_FUNC_NO_RETURN(contextSave);
|
|
|
|
|
g_pmRunOps.enterDeepSleep();
|
|
|
|
|
g_deepSleepOps.rollback();
|
|
|
|
|
}
|
|
|
|
|
//设置唤醒定时器
|
|
|
|
|
g_deepSleepOps.resumeDevice();
|
|
|
|
|
UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer();
|
|
|
|
|
OsSysTimeUpdate(sleepTicks);
|
|
|
|
@ -342,42 +344,43 @@ STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)
|
|
|
|
|
LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID OsEnterSleepMode(VOID)
|
|
|
|
|
STATIC INLINE VOID OsEnterSleepMode(VOID)//进入睡眠模式,包括主核心和其他核心的不同处理
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
UINT32 currCpuid = ArchCurrCpuid();
|
|
|
|
|
if (currCpuid == 0) {
|
|
|
|
|
if (currCpuid == 0) { //如果是0则进入主核心深度睡眠
|
|
|
|
|
#endif
|
|
|
|
|
OsEnterDeepSleepMainCore();
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP //如果当前核心不是主核心,则直接返回,因为其他核心的睡眠处理逻辑不在此函数中处理
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT32 cpuMask = 1 << currCpuid;
|
|
|
|
|
LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1);
|
|
|
|
|
OsSRSaveRegister();
|
|
|
|
|
OsSRSaveRegister();//保存相关寄存器状态并判断是否需要唤醒当前核心。
|
|
|
|
|
if (g_pmMgr.resumeSleepCores & cpuMask) {
|
|
|
|
|
INT32 val;
|
|
|
|
|
do {
|
|
|
|
|
do { //,将 g_pmMgr.resumeSleepCores 的值中当前核心的位清零,表示该核心已被唤醒。
|
|
|
|
|
val = LOS_AtomicRead(&g_pmMgr.resumeSleepCores);
|
|
|
|
|
} while (LOS_AtomicCmpXchg32bits(&g_pmMgr.resumeSleepCores, val & (~cpuMask), val));
|
|
|
|
|
g_deepSleepOps.otherCoreResume();
|
|
|
|
|
UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer();
|
|
|
|
|
OsTickResume(sleepTicks);
|
|
|
|
|
//执行其他核心的恢复操作,并从唤醒定时器中获取休眠时间,然后调用 OsTickResume 函数更新系统时钟。
|
|
|
|
|
} else {
|
|
|
|
|
if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) {
|
|
|
|
|
LOS_MpSchedule(1 << 0);
|
|
|
|
|
if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) {//如果不需要唤醒,则判断是否所有核心都进入了深度睡眠
|
|
|
|
|
LOS_MpSchedule(1 << 0);//调用函数选择一个核心唤醒系统
|
|
|
|
|
}
|
|
|
|
|
#ifdef LOSCFG_KERNEL_TICKLESS
|
|
|
|
|
OsTicklessOpen();
|
|
|
|
|
OsTicklessOpen();//开启节能模式
|
|
|
|
|
#endif
|
|
|
|
|
g_pmRunOps.enterLightSleep();
|
|
|
|
|
}
|
|
|
|
|
LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);
|
|
|
|
|
LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);//将 g_pmMgr.deepSleepCores 的值减1,表示当前核心已经处理完睡眠状态
|
|
|
|
|
#endif // LOSCFG_KERNEL_SMP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)
|
|
|
|
|
STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)//选择合适的低功耗模式(深度,轻度
|
|
|
|
|
{
|
|
|
|
|
// If enterShutdownMode is not defined, will fall through to standby mode
|
|
|
|
|
// If enterStandbyMode is not defined, will fall through to stop mode
|
|
|
|
@ -402,10 +405,10 @@ STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)
|
|
|
|
|
STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)//轻度睡眠中的模式调整
|
|
|
|
|
{
|
|
|
|
|
if (g_pmRunOps.preConfig != NULL) {
|
|
|
|
|
sleepTicks = g_pmRunOps.getSleepTime();
|
|
|
|
|
sleepTicks = g_pmRunOps.getSleepTime();//获取休眠时间
|
|
|
|
|
}
|
|
|
|
|
if (sleepTicks > 1) {
|
|
|
|
|
g_pmMgr.sleepMode[cpuid] = (mode & 0x0FF);
|
|
|
|
@ -414,18 +417,19 @@ STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)
|
|
|
|
|
OsTicklessOpen();
|
|
|
|
|
#endif
|
|
|
|
|
if (mode == LOS_INTERMIT_LIGHT_SLEEP && g_pmRunOps.enterLightSleep != NULL) {
|
|
|
|
|
g_pmRunOps.enterLightSleep();
|
|
|
|
|
g_pmRunOps.enterLightSleep();//进入轻度睡眠
|
|
|
|
|
} else {
|
|
|
|
|
wfi();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;
|
|
|
|
|
g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;//等待中断事件
|
|
|
|
|
g_pmMgr.sleepTime[cpuid] = 0;
|
|
|
|
|
wfi();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 sleepTicks)
|
|
|
|
|
//深度睡眠设置
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_DEEPSLEEP
|
|
|
|
|
if (g_pmRunOps.enterDeepSleep == NULL) {
|
|
|
|
@ -438,27 +442,31 @@ STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 slee
|
|
|
|
|
OsSystemSuspend(mode);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
*mode = LOS_INTERMIT_LIGHT_SLEEP;
|
|
|
|
|
*mode = LOS_INTERMIT_LIGHT_SLEEP;//若不支持深度睡眠则强制进入轻度睡眠
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerProcess(VOID)
|
|
|
|
|
STATIC VOID OsLowpowerProcess(VOID)//处理系统进入低功耗模式的过程
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_RUNSTOP
|
|
|
|
|
#ifdef LOSCFG_KERNEL_RUNSTOP//检查系统是否需要在进入低功耗模式前保存系统消息
|
|
|
|
|
if (OsWowSysDoneFlagGet() == OS_STORE_SYSTEM) {
|
|
|
|
|
OsStoreSystemInfoBeforeSuspend();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
/* Change frequency is pended, need to change the freq here. */
|
|
|
|
|
if ((g_pmRunOps.changeFreq != NULL)) {
|
|
|
|
|
if ((g_pmRunOps.changeFreq != NULL)) {//如果需要改变频率则调整切换
|
|
|
|
|
OsChangeFreq();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//禁止中断,锁住任务调度,并获取当前CPUID和休眠时间
|
|
|
|
|
UINT32 intSave = LOS_IntLock();
|
|
|
|
|
LOS_TaskLock();
|
|
|
|
|
RUNOPS_CALL_FUNC_VOID(preConfig);
|
|
|
|
|
UINT32 cpuid = ArchCurrCpuid();
|
|
|
|
|
UINT32 sleepTicks = g_pmRunOps.getSleepTime();
|
|
|
|
|
/*如果休眠时间小于等于最小休眠时间(g_pmMgr.minSleepTicks)
|
|
|
|
|
或者有任务请求不进入深度睡眠(LOS_PowerMgrGetDeepSleepVoteCount 返回值不为0),
|
|
|
|
|
则将当前 CPU 设置为不进入任何中断模式,清零休眠时间,
|
|
|
|
|
并调用 postConfig 函数。*/
|
|
|
|
|
if (sleepTicks <= g_pmMgr.minSleepTicks || LOS_PowerMgrGetDeepSleepVoteCount() != 0) {
|
|
|
|
|
g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;
|
|
|
|
|
g_pmMgr.sleepTime[cpuid] = 0;
|
|
|
|
@ -477,23 +485,23 @@ STATIC VOID OsLowpowerProcess(VOID)
|
|
|
|
|
sleepTicks = g_pmMgr.maxSleepCount;
|
|
|
|
|
}
|
|
|
|
|
UINT32 mode = g_pmRunOps.selectSleepMode(sleepTicks);
|
|
|
|
|
if (mode >= LOS_INTERMIT_DEEP_SLEEP) {
|
|
|
|
|
if (mode >= LOS_INTERMIT_DEEP_SLEEP) {//如果支持深度睡眠
|
|
|
|
|
g_pmMgr.sleepTime[cpuid] = g_pmRunOps.withdrawWakeUpTimer();
|
|
|
|
|
OsLowpowerDeepSleep(&mode, cpuid, sleepTicks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RUNOPS_CALL_FUNC_VOID(postConfig);
|
|
|
|
|
|
|
|
|
|
if (mode < LOS_INTERMIT_DEEP_SLEEP) {
|
|
|
|
|
if (mode < LOS_INTERMIT_DEEP_SLEEP) {//进入轻度睡眠
|
|
|
|
|
OsLowpowerLightSleep(mode, cpuid, sleepTicks);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOS_TaskUnlock();
|
|
|
|
|
LOS_IntRestore(intSave);
|
|
|
|
|
LOS_IntRestore(intSave);//解锁任务调度并恢复中断
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerWakeupFromReset(VOID)
|
|
|
|
|
STATIC VOID OsLowpowerWakeupFromReset(VOID)//处理系统从重置状态唤醒的情况
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_RUNSTOP
|
|
|
|
|
if (g_resumeFromImg == LOS_RUN_STOP_RESET) {
|
|
|
|
@ -508,7 +516,7 @@ STATIC VOID OsLowpowerWakeupFromReset(VOID)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)
|
|
|
|
|
STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)//用于处理系统从重置状态唤醒的情况
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_TICKLESS
|
|
|
|
|
OsTicklessUpdate(intNum);
|
|
|
|
@ -517,26 +525,27 @@ STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsChangeFreq(VOID)
|
|
|
|
|
STATIC VOID OsChangeFreq(VOID)//处理改变系统频率的操作
|
|
|
|
|
{
|
|
|
|
|
UINT32 freq;
|
|
|
|
|
BOOL ret;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
do {//尝试获取频率切换的自旋锁(通过原子操作实现)
|
|
|
|
|
//如果成功获取锁,则说明没有其他线程正在频率切换过程中,可以继续执行
|
|
|
|
|
ret = LOS_AtomicCmpXchg32bits(&g_pmMgr.freeLock, LOCK_ON, LOCK_OFF);
|
|
|
|
|
if (ret) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
freq = (UINT32)g_pmMgr.freqPending;
|
|
|
|
|
freq = (UINT32)g_pmMgr.freqPending;//获取频率切换的目标频率,并进行频率切换
|
|
|
|
|
if (freq != (UINT32)g_pmMgr.freq) {
|
|
|
|
|
g_pmRunOps.changeFreq(freq);
|
|
|
|
|
g_pmRunOps.changeFreq(freq);//更新频率
|
|
|
|
|
LOS_AtomicSet(&g_pmMgr.freq, (INT32)freq);
|
|
|
|
|
}
|
|
|
|
|
LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);
|
|
|
|
|
LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);//释放自旋锁
|
|
|
|
|
} while (FreqHigher(g_pmMgr.freqPending, freq));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)
|
|
|
|
|
STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)//改变系统频率
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
if (g_pmRunOps.changeFreq == NULL) {
|
|
|
|
@ -554,36 +563,36 @@ STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)
|
|
|
|
|
|
|
|
|
|
// We get a high frequency request, then change it
|
|
|
|
|
if (FreqHigher(g_pmMgr.freqPending, g_pmMgr.freq) && g_pmRunOps.changeFreq != NULL) {
|
|
|
|
|
OsChangeFreq();
|
|
|
|
|
OsChangeFreq();//如果目标频率高于当前频率,并且 g_pmRunOps.changeFreq 不为空,则调用 OsChangeFreq 函数进行频率切换。
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID)
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID)//开始深度睡眠投票
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
LOS_AtomicInc(&g_pmMgr.sleepVoteCount);
|
|
|
|
|
LOS_AtomicInc(&g_pmMgr.sleepVoteCount);//用原子操作将 g_pmMgr.sleepVoteCount 加一,并断言 g_pmMgr.sleepVoteCount 大于零。
|
|
|
|
|
LOS_ASSERT(g_pmMgr.sleepVoteCount > 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID)
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID)//结束深度睡眠投票
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
LOS_AtomicDec(&g_pmMgr.sleepVoteCount);
|
|
|
|
|
LOS_AtomicDec(&g_pmMgr.sleepVoteCount);//原子操作将 g_pmMgr.sleepVoteCount 减一,并断言 g_pmMgr.sleepVoteCount 大于等于零。
|
|
|
|
|
LOS_ASSERT(g_pmMgr.sleepVoteCount >= 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks)
|
|
|
|
|
STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks)//延迟深度睡眠投票
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback)
|
|
|
|
|
STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback)//注册外部投票者
|
|
|
|
|
{
|
|
|
|
|
TRACE_FUNC_CALL();
|
|
|
|
|
g_pmMgr.exVoterHandle = callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)
|
|
|
|
|
STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)//获取深度睡眠投票数
|
|
|
|
|
{
|
|
|
|
|
if (g_pmMgr.exVoterHandle == NULL) {
|
|
|
|
|
return (UINT32)g_pmMgr.sleepVoteCount;
|
|
|
|
@ -593,22 +602,26 @@ STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC PowerMgrOps g_pmOps = {
|
|
|
|
|
.process = OsLowpowerProcess,
|
|
|
|
|
.wakeupFromReset = OsLowpowerWakeupFromReset,
|
|
|
|
|
.resumeFromInterrupt = OsLowpowerWakeupFromInterrupt,
|
|
|
|
|
.changeFreq = OsLowpowerChangeFreq,
|
|
|
|
|
.deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin,
|
|
|
|
|
.deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd,
|
|
|
|
|
.deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay,
|
|
|
|
|
.registerExternalVoter = OsLowpowerRegisterExternalVoter,
|
|
|
|
|
.getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount,
|
|
|
|
|
.getSleepMode = NULL,
|
|
|
|
|
.setSleepMode = NULL,
|
|
|
|
|
.process = OsLowpowerProcess, //该函数指针用于处理低功耗过程,即在进入低功耗模式前需要执行的操作
|
|
|
|
|
.wakeupFromReset = OsLowpowerWakeupFromReset,//该函数指针用于处理从复位状态唤醒时的操作
|
|
|
|
|
.resumeFromInterrupt = OsLowpowerWakeupFromInterrupt,//该函数指针用于处理从中断状态恢复时的操作。
|
|
|
|
|
.changeFreq = OsLowpowerChangeFreq,//该函数指针用于改变系统频率的操作,可以根据需要调整系统的工作频率
|
|
|
|
|
.deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin,//该函数指针用于开始深度休眠投票,即在进入深度休眠模式前需要执行的操作
|
|
|
|
|
.deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd,//该函数指针用于结束深度休眠投票,即在退出深度休眠模式后需要执行的操作
|
|
|
|
|
.deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay,//该函数指针用于处理深度休眠投票延迟的操作,可以根据需要延迟深度休眠的投票
|
|
|
|
|
.registerExternalVoter = OsLowpowerRegisterExternalVoter,//该函数指针用于注册外部投票者,即在系统中存在其他模块也需要参与低功耗投票时的操作
|
|
|
|
|
.getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount,//该函数指针用于获取当前深度休眠投票的数量,可以用来监控系统中参与休眠投票的模块数量
|
|
|
|
|
.getSleepMode = NULL,//该函数指针用于获取当前的睡眠模式,即获取系统当前是否处于睡眠状态
|
|
|
|
|
.setSleepMode = NULL,//该函数指针用于设置睡眠模式,即将系统设置为指定的睡眠模式
|
|
|
|
|
//以上提及的函数均为函数指针
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define FORCE_NULL_CALLBACK (void *)0x3f3f3f3f
|
|
|
|
|
|
|
|
|
|
#define ASSIGN_MEMBER(lhs, rhs, member) \
|
|
|
|
|
//以下定义是用于给结构体成员赋值,如果某个回调函数指针为特殊空值,则将相应的成员置为空,否则进行赋值
|
|
|
|
|
#define ASSIGN_MEMBER(lhs, rhs, member)
|
|
|
|
|
//lhs 是左操作数,表示要赋值的结构体指针;
|
|
|
|
|
//rhs 是右操作数,表示要赋给成员的值;
|
|
|
|
|
//member 是要赋值的结构体成员
|
|
|
|
|
do { \
|
|
|
|
|
if ((rhs)->member == FORCE_NULL_CALLBACK) { \
|
|
|
|
|
(lhs)->member = NULL; \
|
|
|
|
@ -631,16 +644,16 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
|
|
|
|
|
const PowerMgrRunOps *runOps = NULL;
|
|
|
|
|
const PowerMgrDeepSleepOps *deepSleepOps = NULL;
|
|
|
|
|
(void)deepSleepOps;
|
|
|
|
|
if (para != NULL) {
|
|
|
|
|
if (para != NULL) { //如果para为空,则运行操作和深度睡眠操作都为空指针
|
|
|
|
|
runOps = ¶->runOps;
|
|
|
|
|
#ifdef LOSCFG_KERNEL_DEEPSLEEP
|
|
|
|
|
deepSleepOps = ¶->deepSleepOps;
|
|
|
|
|
#endif
|
|
|
|
|
g_pmMgr.minSleepTicks = para->config.minLightSleepTicks;
|
|
|
|
|
g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks;
|
|
|
|
|
g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks;
|
|
|
|
|
g_pmMgr.minSleepTicks = para->config.minLightSleepTicks;//记录了系统中需要从睡眠状态唤醒的 CPU 核心数
|
|
|
|
|
g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks;//用于保护电源管理模块在多线程环境下的并发访问
|
|
|
|
|
g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks;//记录自旋锁是否被释放
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//将传入的运行操作和深度睡眠操作分别赋值给全局变量 g_pmRunOps 和 g_deepSleepOps
|
|
|
|
|
LOS_AtomicSet(&g_pmMgr.resumeSleepCores, 0);
|
|
|
|
|
|
|
|
|
|
LOS_SpinInit(&g_pmMgr.lock);
|
|
|
|
@ -648,25 +661,25 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
|
|
|
|
|
|
|
|
|
|
// verify and assign input operators.
|
|
|
|
|
if (runOps != NULL) {
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq);
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep);
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq);//改变CPU频率
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep);//进入浅度睡眠
|
|
|
|
|
#ifdef LOSCFG_KERNEL_DEEPSLEEP
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep);
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer);
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer);
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep);//进入深度睡眠
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer);//设置唤醒定时器
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer);//撤销定时器
|
|
|
|
|
#else
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, enterDeepSleep);
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, setWakeUpTimer);
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, withdrawWakeUpTimer);
|
|
|
|
|
#endif
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime);
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode);
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig);
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig);
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime);//货的睡眠时间
|
|
|
|
|
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode);//选择不同的睡眠模式
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig);//预配置
|
|
|
|
|
ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig);//后配置
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_DEEPSLEEP
|
|
|
|
|
if (deepSleepOps != NULL) {
|
|
|
|
|
if (deepSleepOps != NULL) {//进入深度睡眠
|
|
|
|
|
ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, couldDeepSleep);
|
|
|
|
|
ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, systemWakeup);
|
|
|
|
|
ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, suspendPreConfig);
|
|
|
|
@ -680,4 +693,7 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
|
|
|
|
|
#endif
|
|
|
|
|
// Register PowerMgr to Low-Power Framework.
|
|
|
|
|
LOS_LowpowerInit(&g_pmOps);
|
|
|
|
|
//将电源管理模块注册到低功耗框架中。
|
|
|
|
|
//低功耗框架是一个用于管理处理器和设备进入低功耗模式的软件框架,
|
|
|
|
|
//它能够最大限度地降低系统能耗,提高系统的电池寿命
|
|
|
|
|
}
|
|
|
|
|