diff --git a/BUILD.gn b/BUILD.gn
index fb72bf31..e1518d39 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -35,6 +35,7 @@ declare_args() {
enable_ohos_kernel_liteos_m_fs = true
enable_ohos_kernel_liteos_m_backtrace = true
enable_ohos_kernel_liteos_m_test = false
+ enable_ohos_kernel_liteos_m_pm = true
}
group("kernel") {
@@ -58,6 +59,9 @@ group("kernel") {
if (enable_ohos_kernel_liteos_m_fs == true) {
deps += [ "components/fs:fs" ]
}
+ if (enable_ohos_kernel_liteos_m_pm == true) {
+ deps += [ "components/power:pm" ]
+ }
if (enable_ohos_kernel_liteos_m_kal == true) {
deps += [ "kal:kal" ]
}
diff --git a/components/power/BUILD.gn b/components/power/BUILD.gn
new file mode 100644
index 00000000..d75e908f
--- /dev/null
+++ b/components/power/BUILD.gn
@@ -0,0 +1,39 @@
+# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
+# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice, this list
+# of conditions and the following disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+static_library("pm") {
+ sources = [ "los_pm.c" ]
+
+ include_dirs = [
+ "../../kernel/include",
+ "../../kernel/arch/include",
+ "../../utils",
+ "//third_party/bounds_checking_function/include",
+ ]
+}
diff --git a/components/power/los_pm.c b/components/power/los_pm.c
new file mode 100644
index 00000000..9bc933f5
--- /dev/null
+++ b/components/power/los_pm.c
@@ -0,0 +1,663 @@
+/*
+ * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "los_pm.h"
+#include "securec.h"
+#include "los_sched.h"
+#include "los_timer.h"
+#include "los_memory.h"
+
+#if (LOSCFG_KERNEL_PM == 1)
+#define OS_PM_NODE_FREE 0x80000000U
+#define OS_PM_LOCK_MAX 0xFFFFU
+
+typedef UINT32 (*Suspend)(VOID);
+
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+typedef struct {
+ CHAR *name;
+ UINT32 count;
+ LOS_DL_LIST list;
+} OsPmLockCB;
+#endif
+
+typedef struct {
+ LOS_SysSleepEnum pmMode;
+ LOS_SysSleepEnum sysMode;
+ UINT16 lock;
+ BOOL isWake;
+ LosPmDevice *device;
+ LosPmSysctrl *sysctrl;
+ LosPmTickTimer *tickTimer;
+#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
+ UINT64 enterSleepTime;
+#endif
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ LOS_DL_LIST lockList;
+#endif
+} LosPmCB;
+
+STATIC LosPmCB g_pmCB;
+STATIC LosPmSysctrl *g_sysctrl = NULL;
+STATIC UINT64 g_pmSleepTime;
+
+#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
+STATIC VOID OsPmTickTimerStart(LosPmCB *pm)
+{
+ UINT32 intSave;
+ UINT64 currTime, sleepTime, realSleepTime;
+ LosPmTickTimer *tickTimer = pm->tickTimer;
+
+ intSave = LOS_IntLock();
+ /* Restore the main CPU frequency */
+ sleepTime = tickTimer->timerCycleGet();
+ tickTimer->timerStop();
+
+ realSleepTime = OS_SYS_CYCLE_TO_NS(sleepTime, tickTimer->freq);
+ realSleepTime = OS_SYS_NS_TO_CYCLE(realSleepTime, OS_SYS_CLOCK);
+ currTime = pm->enterSleepTime + realSleepTime;
+ pm->enterSleepTime = 0;
+
+ OsSchedTimerBaseReset(currTime);
+ OsSchedUpdateExpireTime(currTime, FALSE);
+ tickTimer->tickUnlock();
+ LOS_IntRestore(intSave);
+ return;
+}
+
+STATIC VOID OsPmTickTimerStop(LosPmCB *pm)
+{
+ UINT64 sleepCycle;
+ UINT64 realSleepTime = g_pmSleepTime;
+ LosPmTickTimer *tickTimer = pm->tickTimer;
+
+ if (realSleepTime == 0) {
+ return;
+ }
+
+ sleepCycle = OS_SYS_CYCLE_TO_NS(realSleepTime, OS_SYS_CLOCK);
+ sleepCycle = OS_SYS_NS_TO_CYCLE(sleepCycle, tickTimer->freq);
+
+ /* The main CPU reduces the frequency */
+ pm->enterSleepTime = OsGetCurrSchedTimeCycle();
+ tickTimer->tickLock();
+ tickTimer->timerStart(sleepCycle);
+ return;
+}
+#endif
+
+STATIC VOID OsPmTickTimerResume(LosPmCB *pm)
+{
+ if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->tickTimer->tickUnlock != NULL)) {
+ pm->tickTimer->tickUnlock();
+ } else {
+#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
+ /* Sys tick timer is restored from low power mode */
+ if (pm->enterSleepTime != 0) {
+ OsPmTickTimerStart(pm);
+ }
+#endif
+ }
+}
+
+STATIC VOID OsPmCpuResume(LosPmCB *pm)
+{
+ if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) {
+ pm->sysctrl->normalResume();
+ } else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) {
+ pm->sysctrl->lightResume();
+ } else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) {
+ pm->sysctrl->deepResume();
+ }
+}
+
+STATIC Suspend OsPmCpuSuspend(LosPmCB *pm)
+{
+ Suspend sysSuspend = NULL;
+
+ /* cpu enter low power mode */
+ LOS_ASSERT(pm->sysctrl != NULL);
+
+ if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) {
+ sysSuspend = pm->sysctrl->normalSuspend;
+ } else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) {
+ sysSuspend = pm->sysctrl->lightSuspend;
+ } else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) {
+ sysSuspend = pm->sysctrl->deepSuspend;
+ } else {
+ sysSuspend = pm->sysctrl->shutdownSuspend;
+ }
+
+ LOS_ASSERT(sysSuspend != NULL);
+
+ return sysSuspend;
+}
+
+STATIC VOID OsPmTickTimerSuspend(LosPmCB *pm)
+{
+ if (((pm->sysMode == LOS_SYS_DEEP_SLEEP) || (pm->sysMode == LOS_SYS_SHUTDOWN)) &&
+ (pm->tickTimer->tickLock != NULL)) {
+ pm->tickTimer->tickLock();
+ } else {
+#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
+ /* Sys tick timer enter low power mode */
+ if (pm->tickTimer == NULL) {
+ return;
+ }
+
+ if ((pm->tickTimer->timerStart != NULL) &&
+ (pm->tickTimer->timerStop != NULL) &&
+ (pm->tickTimer->timerCycleGet == NULL) &&
+ (pm->tickTimer->freq != 0)) {
+ OsPmTickTimerStop(pm);
+ }
+#endif
+ }
+}
+
+STATIC VOID OsPmEnter(BOOL isIdle)
+{
+ UINT32 ret;
+ UINT32 intSave;
+ Suspend sysSuspend = NULL;
+ LosPmCB *pm = &g_pmCB;
+ BOOL isTaskLock = FALSE;
+
+ intSave = LOS_IntLock();
+ pm->sysMode = pm->pmMode;
+ if (isIdle) {
+ if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->sysMode != LOS_SYS_LIGHT_SLEEP)) {
+ pm->sysMode = LOS_SYS_NORMAL_SLEEP;
+ }
+ } else {
+ if ((pm->sysMode != LOS_SYS_DEEP_SLEEP) && (pm->sysMode != LOS_SYS_SHUTDOWN)) {
+ LOS_IntRestore(intSave);
+ return;
+ }
+ }
+
+ if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) || (pm->sysMode == LOS_SYS_LIGHT_SLEEP)) {
+ if (pm->lock > 0) {
+ pm->sysMode = LOS_SYS_NORMAL_SLEEP;
+ }
+ } else if (pm->lock > 0) {
+ LOS_IntRestore(intSave);
+ return;
+ }
+
+ if (pm->sysMode != LOS_SYS_NORMAL_SLEEP) {
+ pm->isWake = FALSE;
+ LOS_TaskLock();
+ isTaskLock = TRUE;
+
+ ret = pm->device->suspend((UINT32)pm->sysMode);
+ if (ret != LOS_OK) {
+ goto EXIT;
+ }
+ }
+
+ OsPmTickTimerSuspend(pm);
+
+ sysSuspend = OsPmCpuSuspend(pm);
+ LOS_IntRestore(intSave);
+
+ if (!isTaskLock || (isTaskLock && !pm->isWake)) {
+ (VOID)sysSuspend();
+ }
+
+ intSave = LOS_IntLock();
+
+ OsPmCpuResume(pm);
+
+ OsPmTickTimerResume(pm);
+
+ if (pm->sysMode != LOS_SYS_NORMAL_SLEEP) {
+ pm->device->resume((UINT32)pm->sysMode);
+ }
+
+ if (pm->pmMode == LOS_SYS_DEEP_SLEEP) {
+ pm->pmMode = LOS_SYS_NORMAL_SLEEP;
+ }
+
+EXIT:
+ LOS_IntRestore(intSave);
+
+ if (isTaskLock) {
+ LOS_TaskUnlock();
+ }
+ return;
+}
+
+STATIC VOID OsPmTask(VOID)
+{
+ OsPmEnter(FALSE);
+}
+
+STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)
+{
+ UINT32 intSave;
+
+ if ((device->suspend == NULL) || (device->resume == NULL)) {
+ return LOS_ERRNO_PM_INVALID_PARAM;
+ }
+
+ intSave = LOS_IntLock();
+ pm->device = device;
+ LOS_IntRestore(intSave);
+
+ return LOS_OK;
+}
+
+STATIC UINT32 OsPmTickTimerRegister(LosPmCB *pm, LosPmTickTimer *tickTimer)
+{
+ UINT32 intSave;
+
+ intSave = LOS_IntLock();
+#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
+ pm->enterSleepTime = 0;
+#endif
+ pm->tickTimer = tickTimer;
+ LOS_IntRestore(intSave);
+ return LOS_OK;
+}
+
+STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)
+{
+ UINT32 intSave;
+
+ if (sysctrl->normalSuspend == NULL) {
+ return LOS_ERRNO_PM_INVALID_PARAM;
+ }
+
+ intSave = LOS_IntLock();
+ pm->sysctrl = sysctrl;
+ LOS_IntRestore(intSave);
+
+ return LOS_OK;
+}
+
+UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node)
+{
+ LosPmCB *pm = &g_pmCB;
+
+ if (node == NULL) {
+ return LOS_ERRNO_PM_INVALID_PARAM;
+ }
+
+ switch (type) {
+ case LOS_PM_TYPE_DEVICE:
+ return OsPmDeviceRegister(pm, (LosPmDevice *)node);
+ case LOS_PM_TYPE_TICK_TIMER:
+ return OsPmTickTimerRegister(pm, (LosPmTickTimer *)node);
+ case LOS_PM_TYPE_SYSCTRL:
+ return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node);
+ default:
+ break;
+ }
+
+ return LOS_ERRNO_PM_INVALID_TYPE;
+}
+
+STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, LosPmDevice *device)
+{
+ UINT32 intSave;
+
+ intSave = LOS_IntLock();
+ if (pm->device == device) {
+ pm->device = NULL;
+ pm->pmMode = LOS_SYS_NORMAL_SLEEP;
+ LOS_IntRestore(intSave);
+ return LOS_OK;
+ }
+
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_INVALID_NODE;
+}
+
+STATIC UINT32 OsPmTickTimerUnregister(LosPmCB *pm, LosPmTickTimer *tickTimer)
+{
+ UINT32 intSave;
+
+ intSave = LOS_IntLock();
+ if (pm->tickTimer == tickTimer) {
+ pm->tickTimer = NULL;
+ if ((pm->pmMode != LOS_SYS_NORMAL_SLEEP) && (pm->pmMode != LOS_SYS_LIGHT_SLEEP)) {
+ pm->pmMode = LOS_SYS_NORMAL_SLEEP;
+ }
+ LOS_IntRestore(intSave);
+ return LOS_OK;
+ }
+
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_INVALID_NODE;
+}
+
+STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)
+{
+ UINT32 intSave;
+ VOID *freeNode = NULL;
+
+ intSave = LOS_IntLock();
+ if (pm->sysctrl == sysctrl) {
+ if (pm->sysctrl == g_sysctrl) {
+ freeNode = (VOID *)pm->sysctrl;
+ g_sysctrl = NULL;
+ }
+
+ pm->sysctrl = NULL;
+ LOS_IntRestore(intSave);
+
+ if (freeNode != NULL) {
+ (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, freeNode);
+ }
+ return LOS_OK;
+ }
+
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_INVALID_NODE;
+}
+
+UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node)
+{
+ LosPmCB *pm = &g_pmCB;
+
+ if (node == NULL) {
+ return LOS_ERRNO_PM_INVALID_PARAM;
+ }
+
+ switch (type) {
+ case LOS_PM_TYPE_DEVICE:
+ return OsPmDeviceUnregister(pm, (LosPmDevice *)node);
+ case LOS_PM_TYPE_TICK_TIMER:
+ return OsPmTickTimerUnregister(pm, (LosPmTickTimer *)node);
+ case LOS_PM_TYPE_SYSCTRL:
+ return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node);
+ default:
+ break;
+ }
+
+ return LOS_ERRNO_PM_INVALID_TYPE;
+}
+
+VOID LOS_PmWakeSet(VOID)
+{
+ UINT32 intSave;
+ LosPmCB *pm = &g_pmCB;
+
+ intSave = LOS_IntLock();
+ pm->isWake = TRUE;
+ LOS_IntRestore(intSave);
+ return;
+}
+
+LOS_SysSleepEnum LOS_PmModeGet(VOID)
+{
+ LOS_SysSleepEnum mode;
+ LosPmCB *pm = &g_pmCB;
+
+ UINT32 intSave = LOS_IntLock();
+ mode = pm->pmMode;
+ LOS_IntRestore(intSave);
+
+ return mode;
+}
+
+UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode)
+{
+ UINT32 intSave;
+ UINT32 taskID;
+ UINT32 ret;
+ LosPmCB *pm = &g_pmCB;
+ INT32 sleepMode = (INT32)mode;
+ TSK_INIT_PARAM_S taskInitParam = { 0 };
+
+ if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) {
+ return LOS_ERRNO_PM_INVALID_MODE;
+ }
+
+ intSave = LOS_IntLock();
+ if ((mode != LOS_SYS_NORMAL_SLEEP) && (pm->device == NULL)) {
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_DEVICE_NULL;
+ }
+
+ if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) {
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_HANDLER_NULL;
+ }
+
+ if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) {
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_HANDLER_NULL;
+ }
+
+ if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) {
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_HANDLER_NULL;
+ }
+
+ if ((mode == LOS_SYS_DEEP_SLEEP) || (mode == LOS_SYS_SHUTDOWN)) {
+ if ((pm->tickTimer == NULL) ||
+ (pm->tickTimer->tickLock == NULL) ||
+ (pm->tickTimer->tickUnlock == NULL)) {
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_TICK_TIMER_NULL;
+ }
+ }
+
+ pm->pmMode = mode;
+ LOS_IntRestore(intSave);
+
+ if ((mode == LOS_SYS_DEEP_SLEEP) || (mode == LOS_SYS_SHUTDOWN)) {
+ taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsPmTask;
+ taskInitParam.uwStackSize = LOSCFG_KERNEL_PM_TASK_STACKSIZE;
+ taskInitParam.pcName = "pm";
+ taskInitParam.usTaskPrio = LOSCFG_KERNEL_PM_TASK_PTIORITY;
+ ret = LOS_TaskCreate(&taskID, &taskInitParam);
+ if (ret != LOS_OK) {
+ return ret;
+ }
+ }
+
+ return LOS_OK;
+}
+
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+VOID LOS_PmLockInfoShow(VOID)
+{
+ UINT32 intSave;
+ LosPmCB *pm = &g_pmCB;
+ OsPmLockCB *lock = NULL;
+ LOS_DL_LIST *head = &pm->lockList;
+ LOS_DL_LIST *list = head->pstNext;
+
+ PRINTK("Name Count\n\r");
+
+ intSave = LOS_IntLock();
+ while (list != head) {
+ lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
+ PRINTK("%-30s%5u\n\r", lock->name, lock->count);
+ list = list->pstNext;
+ }
+ LOS_IntRestore(intSave);
+
+ return;
+}
+#endif
+
+UINT32 LOS_PmLockRequest(const CHAR *name)
+{
+ UINT32 intSave;
+ UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
+ LosPmCB *pm = &g_pmCB;
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ OsPmLockCB *listNode = NULL;
+ OsPmLockCB *lock = NULL;
+ LOS_DL_LIST *head = &pm->lockList;
+ LOS_DL_LIST *list = head->pstNext;
+
+ if (name == NULL) {
+ return LOS_ERRNO_PM_INVALID_PARAM;
+ }
+#endif
+
+ intSave = LOS_IntLock();
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ while (list != head) {
+ listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
+ if (strcmp(name, listNode->name) == 0) {
+ lock = listNode;
+ break;
+ }
+
+ list = list->pstNext;
+ }
+
+ if (lock == NULL) {
+ lock = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(OsPmLockCB));
+ if (lock == NULL) {
+ LOS_IntRestore(intSave);
+ return LOS_NOK;
+ }
+ lock->name = (CHAR *)name;
+ lock->count = 1;
+ LOS_ListTailInsert(head, &lock->list);
+ } else if (lock->count < OS_PM_LOCK_MAX) {
+ lock->count++;
+ }
+#endif
+
+ if (pm->lock < OS_PM_LOCK_MAX) {
+ pm->lock++;
+ ret = LOS_OK;
+ }
+
+ LOS_IntRestore(intSave);
+ return ret;
+}
+
+UINT32 LOS_PmLockRelease(const CHAR *name)
+{
+ UINT32 intSave;
+ UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
+ LosPmCB *pm = &g_pmCB;
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ OsPmLockCB *lock = NULL;
+ OsPmLockCB *listNode = NULL;
+ LOS_DL_LIST *head = &pm->lockList;
+ LOS_DL_LIST *list = head->pstNext;
+ VOID *lockFree = NULL;
+
+ if (name == NULL) {
+ return LOS_ERRNO_PM_INVALID_PARAM;
+ }
+#endif
+
+ intSave = LOS_IntLock();
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ while (list != head) {
+ listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
+ if (strcmp(name, listNode->name) == 0) {
+ lock = listNode;
+ break;
+ }
+
+ list = list->pstNext;
+ }
+
+ if (lock == NULL) {
+ LOS_IntRestore(intSave);
+ return LOS_ERRNO_PM_NOT_LOCK;
+ } else if (lock->count > 0) {
+ lock->count--;
+ if (lock->count == 0) {
+ LOS_ListDelete(&lock->list);
+ lockFree = lock;
+ }
+ }
+#endif
+
+ if (pm->lock > 0) {
+ pm->lock--;
+ ret = LOS_OK;
+ }
+
+ LOS_IntRestore(intSave);
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
+#endif
+ return ret;
+}
+
+STATIC VOID OsPmSleepTimeSet(UINT64 sleepTime)
+{
+ g_pmSleepTime = sleepTime;
+}
+
+UINT32 OsPmInit(VOID)
+{
+ UINT32 ret;
+ LosPmCB *pm = &g_pmCB;
+
+ (VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
+
+ pm->pmMode = LOS_SYS_NORMAL_SLEEP;
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+ LOS_ListInit(&pm->lockList);
+#endif
+
+ ret = OsSchedRealSleepTimeSet(OsPmSleepTimeSet);
+ if (ret != LOS_OK) {
+ return ret;
+ }
+
+ ret = OsPmEnterHandlerSet(OsPmEnter);
+ if (ret != LOS_OK) {
+ return ret;
+ }
+
+ g_sysctrl = (LosPmSysctrl *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(LosPmSysctrl));
+ if (g_sysctrl == NULL) {
+ return LOS_NOK;
+ }
+
+ (VOID)memset_s(g_sysctrl, sizeof(LosPmSysctrl), 0, sizeof(LosPmSysctrl));
+ g_sysctrl->normalSuspend = HalEnterSleep;
+
+ ret = LOS_PmRegister(LOS_PM_TYPE_SYSCTRL, (VOID *)g_sysctrl);
+ if (ret != LOS_OK) {
+ (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, g_sysctrl);
+ g_sysctrl = NULL;
+ }
+
+ return ret;
+}
+#endif
diff --git a/components/power/los_pm.h b/components/power/los_pm.h
new file mode 100644
index 00000000..5564de6d
--- /dev/null
+++ b/components/power/los_pm.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LOS_PM_H
+#define _LOS_PM_H
+
+#include "los_config.h"
+#include "los_compiler.h"
+#include "los_list.h"
+#include "los_error.h"
+
+/**
+ * @ingroup los_pm
+ * Pm error code: Invalid low power mode.
+ *
+ * Value: 0x02002001
+ *
+ */
+#define LOS_ERRNO_PM_INVALID_MODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x01)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: Invalid input parameter.
+ *
+ * Value: 0x02002002
+ *
+ */
+#define LOS_ERRNO_PM_INVALID_PARAM LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x02)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: The current mode is unlocked.
+ *
+ * Value: 0x02002003
+ *
+ */
+#define LOS_ERRNO_PM_NOT_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x03)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: The lock limit has been exceeded.
+ *
+ * Value: 0x02002004
+ *
+ */
+#define LOS_ERRNO_PM_LOCK_LIMIT LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x04)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: Invalid device node.
+ *
+ * Value: 0x02002005
+ *
+ */
+#define LOS_ERRNO_PM_INVALID_NODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x05)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: Invalid type.
+ *
+ * Value: 0x02002006
+ *
+ */
+#define LOS_ERRNO_PM_INVALID_TYPE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x06)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: The hook for mode is not implemented.
+ *
+ * Value: 0x02002007
+ *
+ */
+#define LOS_ERRNO_PM_HANDLER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x07)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: Deep and shutdown must implement the Tick Timer related interface.
+ *
+ * Value: 0x02002008
+ *
+ */
+#define LOS_ERRNO_PM_TICK_TIMER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x08)
+
+/**
+ * @ingroup los_pm
+ * Pm error code: Device is not registered.
+ *
+ * Value: 0x02002009
+ *
+ */
+#define LOS_ERRNO_PM_DEVICE_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x09)
+
+typedef enum {
+ LOS_SYS_NORMAL_SLEEP = 0,
+ LOS_SYS_LIGHT_SLEEP,
+ LOS_SYS_DEEP_SLEEP,
+ LOS_SYS_SHUTDOWN,
+} LOS_SysSleepEnum;
+
+typedef enum {
+ LOS_PM_TYPE_DEVICE = 0,
+ LOS_PM_TYPE_TICK_TIMER,
+ LOS_PM_TYPE_SYSCTRL,
+} LOS_PmNodeType;
+
+typedef struct {
+ UINT32 (*suspend)(UINT32 mode);
+ VOID (*resume)(UINT32 mode);
+} LosPmDevice;
+
+typedef struct {
+ UINT32 freq; /* The frequency of the low power timer */
+ VOID (*timerStart)(UINT64); /* Start the low power timer */
+ VOID (*timerStop)(VOID); /* Stop the low power timer */
+ UINT64 (*timerCycleGet)(VOID); /* Gets the running time of the low power timer in unit cycle */
+ VOID (*tickLock)(VOID); /* Pause the system tick timer */
+ VOID (*tickUnlock)(VOID); /* Restore the system tick timer */
+} LosPmTickTimer;
+
+typedef struct {
+ UINT32 (*normalSuspend)(VOID);
+ VOID (*normalResume)(VOID);
+ UINT32 (*lightSuspend)(VOID);
+ VOID (*lightResume)(VOID);
+ UINT32 (*deepSuspend)(VOID);
+ VOID (*deepResume)(VOID);
+ UINT32 (*shutdownSuspend)(VOID);
+ VOID (*shutdownResume)(VOID);
+} LosPmSysctrl;
+
+/**
+ * @ingroup los_pm
+ * @brief Initialize system low power frame.
+ *
+ * @par Description:
+ * This API is used to initialize the system low power frame.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ *
- los_pm.h: the header file that contains the API declaration.
+ * @see
+ */
+UINT32 OsPmInit(VOID);
+
+/**
+ * @ingroup los_pm
+ * @brief Register a power management node.
+ *
+ * @par Description:
+ * This API is used to register a power management node.
+ *
+ * @attention None.
+ *
+ * @param type [IN] The types supported by the PM module.
+ * @param node [IN] power management node.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmUnregister
+ */
+UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node);
+
+/**
+ * @ingroup los_pm
+ * @brief Unregister a power management node.
+ *
+ * @par Description:
+ * This API is used to unregister a power management node.
+ *
+ * @attention None.
+ *
+ * @param type [IN] The types supported by the PM module.
+ * @param node [IN] power management node.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmRegister
+ */
+UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node);
+
+/**
+ * @ingroup los_pm
+ * @brief Set the system wake up flag.
+ *
+ * @par Description:
+ * This API is used to set the system wake-up flag.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval None.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see
+ */
+VOID LOS_PmWakeSet(VOID);
+
+/**
+ * @ingroup los_pm
+ * @brief Get the low power mode of the current system.
+ *
+ * @par Description:
+ * This API is used to get the low power mode of the current system.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmModeSet
+ */
+LOS_SysSleepEnum LOS_PmModeGet(VOID);
+
+/**
+ * @ingroup los_pm
+ * @brief Set low power mode.
+ *
+ * @par Description:
+ * This API is used to set low power mode.
+ *
+ * @attention None.
+ *
+ * @param mode [IN] low power mode.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmModeGet
+ */
+UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode);
+
+/**
+ * @ingroup los_pm
+ * @brief Request to obtain the lock in current mode, so that the system will not enter
+ * this mode when it enters the idle task next time.
+ *
+ * @par Description:
+ * This API is used to obtain the lock in current mode.
+ *
+ * @attention None.
+ *
+ * @param name [IN] Who requests the lock.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmLockRelease
+ */
+UINT32 LOS_PmLockRequest(const CHAR *name);
+
+/**
+ * @ingroup los_pm
+ * @brief Release the lock in current mode so that the next time the system enters
+ * the idle task, it will enter this mode.
+ *
+ * @par Description:
+ * This API is used to release the lock in current mode.
+ *
+ * @attention None.
+ *
+ * @param name [IN] Who releases the lock.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmLockRequest
+ */
+UINT32 LOS_PmLockRelease(const CHAR *name);
+
+#if (LOSCFG_KERNEL_PM_DEBUG == 1)
+/**
+ * @ingroup los_pm
+ * @brief Output the locking information of the pm lock.
+ *
+ * @par Description:
+ * This API is used to output the locking information of the pm lock.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval error code, LOS_OK means success.
+ * @par Dependency:
+ * - los_pm.h: the header file that contains the API declaration.
+ * @see LOS_PmLockRequest
+ */
+VOID LOS_PmLockInfoShow(VOID);
+#endif
+#endif
diff --git a/kernel/BUILD.gn b/kernel/BUILD.gn
index 7d7d7e64..ae9c3420 100644
--- a/kernel/BUILD.gn
+++ b/kernel/BUILD.gn
@@ -49,6 +49,7 @@ static_library("kernel") {
"../components/cpup",
"../components/exchook",
"../components/backtrace",
+ "../components/power",
"../utils",
"//third_party/bounds_checking_function/include",
]
diff --git a/kernel/arch/arm/cortex-m3/keil/los_interrupt.c b/kernel/arch/arm/cortex-m3/keil/los_interrupt.c
index 82bfb304..0dee58cf 100644
--- a/kernel/arch/arm/cortex-m3/keil/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m3/keil/los_interrupt.c
@@ -40,7 +40,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -169,10 +168,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
g_intCount++;
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m3/keil/los_timer.c b/kernel/arch/arm/cortex-m3/keil/los_timer.c
index fcdffde3..f51faf35 100644
--- a/kernel/arch/arm/cortex-m3/keil/los_timer.c
+++ b/kernel/arch/arm/cortex-m3/keil/los_timer.c
@@ -103,15 +103,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+
+ return LOS_OK;
}
diff --git a/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c
index f677a565..c5952da6 100644
--- a/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c
@@ -40,7 +40,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -159,10 +158,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
g_intCount++;
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m33/gcc/los_timer.c b/kernel/arch/arm/cortex-m33/gcc/los_timer.c
index e4a0160e..9e27972d 100644
--- a/kernel/arch/arm/cortex-m33/gcc/los_timer.c
+++ b/kernel/arch/arm/cortex-m33/gcc/los_timer.c
@@ -102,15 +102,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+
+ return LOS_OK;
}
diff --git a/kernel/arch/arm/cortex-m33/iar/NTZ/los_interrupt.c b/kernel/arch/arm/cortex-m33/iar/NTZ/los_interrupt.c
index d1570719..283b7234 100644
--- a/kernel/arch/arm/cortex-m33/iar/NTZ/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m33/iar/NTZ/los_interrupt.c
@@ -41,7 +41,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -168,10 +167,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m33/iar/NTZ/los_timer.c b/kernel/arch/arm/cortex-m33/iar/NTZ/los_timer.c
index bebda6f8..72792526 100644
--- a/kernel/arch/arm/cortex-m33/iar/NTZ/los_timer.c
+++ b/kernel/arch/arm/cortex-m33/iar/NTZ/los_timer.c
@@ -102,15 +102,10 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+ return LOS_OK;
}
diff --git a/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_interrupt.c b/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_interrupt.c
index d1570719..283b7234 100644
--- a/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_interrupt.c
@@ -41,7 +41,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -168,10 +167,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_timer.c b/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_timer.c
index bebda6f8..7212e2c4 100644
--- a/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_timer.c
+++ b/kernel/arch/arm/cortex-m33/iar/TZ/non_secure/los_timer.c
@@ -102,15 +102,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+
+ return LOS_OK;
}
diff --git a/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c
index 444ec2c2..6ab35187 100644
--- a/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c
@@ -40,7 +40,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -169,10 +168,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
g_intCount++;
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m4/gcc/los_timer.c b/kernel/arch/arm/cortex-m4/gcc/los_timer.c
index e201c8b4..24f9b09d 100644
--- a/kernel/arch/arm/cortex-m4/gcc/los_timer.c
+++ b/kernel/arch/arm/cortex-m4/gcc/los_timer.c
@@ -103,16 +103,12 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+
+ return LOS_OK;
}
diff --git a/kernel/arch/arm/cortex-m4/iar/los_interrupt.c b/kernel/arch/arm/cortex-m4/iar/los_interrupt.c
index 6b37e84a..cd7ff15c 100644
--- a/kernel/arch/arm/cortex-m4/iar/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m4/iar/los_interrupt.c
@@ -41,7 +41,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -172,10 +171,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m4/iar/los_timer.c b/kernel/arch/arm/cortex-m4/iar/los_timer.c
index e201c8b4..70bbc091 100644
--- a/kernel/arch/arm/cortex-m4/iar/los_timer.c
+++ b/kernel/arch/arm/cortex-m4/iar/los_timer.c
@@ -103,16 +103,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
-}
+ return LOS_OK;
+}
diff --git a/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c
index 1124790f..e1eb52e3 100644
--- a/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c
@@ -40,7 +40,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -159,10 +158,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
g_intCount++;
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m7/gcc/los_timer.c b/kernel/arch/arm/cortex-m7/gcc/los_timer.c
index e4a0160e..9e27972d 100644
--- a/kernel/arch/arm/cortex-m7/gcc/los_timer.c
+++ b/kernel/arch/arm/cortex-m7/gcc/los_timer.c
@@ -102,15 +102,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+
+ return LOS_OK;
}
diff --git a/kernel/arch/arm/cortex-m7/iar/los_interrupt.c b/kernel/arch/arm/cortex-m7/iar/los_interrupt.c
index 931c93b9..6c5adc22 100644
--- a/kernel/arch/arm/cortex-m7/iar/los_interrupt.c
+++ b/kernel/arch/arm/cortex-m7/iar/los_interrupt.c
@@ -41,7 +41,6 @@
#include "los_memory.h"
#include "los_membox.h"
-
/*lint -save -e40 -e522 -e533*/
UINT32 g_intCount = 0;
@@ -168,10 +167,6 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
LOS_IntRestore(intSave);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- OsSchedUpdateSleepTime();
-#endif
-
hwiIndex = HalIntNumGet();
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
diff --git a/kernel/arch/arm/cortex-m7/iar/los_timer.c b/kernel/arch/arm/cortex-m7/iar/los_timer.c
index e4a0160e..9e27972d 100644
--- a/kernel/arch/arm/cortex-m7/iar/los_timer.c
+++ b/kernel/arch/arm/cortex-m7/iar/los_timer.c
@@ -102,15 +102,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__DSB();
__WFI();
__ISB();
+
+ return LOS_OK;
}
diff --git a/kernel/arch/include/los_timer.h b/kernel/arch/include/los_timer.h
index 52d25020..f9f3f5e0 100644
--- a/kernel/arch/include/los_timer.h
+++ b/kernel/arch/include/los_timer.h
@@ -52,20 +52,11 @@ extern "C" {
#define RTC_CALIBRATE_SLEEP_TIME 8
#define MACHINE_CYCLE_DEALAY_TIMES (LOSCFG_BASE_CORE_TICK_PER_SECOND << 2)
-typedef enum {
- OS_SYS_NORMAL_SLEEP = 0,
- OS_SYS_DEEP_SLEEP,
-} LOS_SysSleepEnum;
-
VOID HalTickLock(VOID);
VOID HalTickUnlock(VOID);
-BOOL HalGetSysSleepFlag(VOID);
-
-VOID HalClearSysSleepFlag(VOID);
-
-VOID HalEnterSleep(LOS_SysSleepEnum sleep);
+UINT32 HalEnterSleep(VOID);
/**
* @ingroup los_timer
diff --git a/kernel/arch/risc-v/nuclei/gcc/los_timer.c b/kernel/arch/risc-v/nuclei/gcc/los_timer.c
index 2b3cac7e..6faffcde 100644
--- a/kernel/arch/risc-v/nuclei/gcc/los_timer.c
+++ b/kernel/arch/risc-v/nuclei/gcc/los_timer.c
@@ -109,16 +109,11 @@ WEAK VOID HalTickUnlock(VOID)
SysTimer_Start();
}
-
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
__WFI();
+
+ return LOS_OK;
}
#ifdef __cplusplus
diff --git a/kernel/arch/risc-v/riscv32/gcc/los_timer.c b/kernel/arch/risc-v/riscv32/gcc/los_timer.c
index 6011626d..38f27706 100644
--- a/kernel/arch/risc-v/riscv32/gcc/los_timer.c
+++ b/kernel/arch/risc-v/riscv32/gcc/los_timer.c
@@ -76,14 +76,10 @@ WEAK UINT64 HalGetTickCycle(UINT32 *period)
return OS_COMBINED_64(timerH, timerL);
}
-VOID HalEnterSleep(LOS_SysSleepEnum sleep)
+UINT32 HalEnterSleep(VOID)
{
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- if (sleep == OS_SYS_DEEP_SLEEP) {
- OsSchedToSleep();
- }
-#endif
-
wfi();
+
+ return LOS_OK;
}
diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h
index 097de7a7..b3a16d28 100644
--- a/kernel/include/los_config.h
+++ b/kernel/include/los_config.h
@@ -634,10 +634,34 @@ extern UINT8 *m_aucSysMem0;
/**
* @ingroup los_config
- * When the tick timer is a non-64/128-bit timer, it has ultra-low power compensation.
+ * Configuration item for low power frame tailoring
*/
-#ifndef LOSCFG_BASE_CORE_SCHED_SLEEP
-#define LOSCFG_BASE_CORE_SCHED_SLEEP 0
+#ifndef LOSCFG_KERNEL_PM
+#define LOSCFG_KERNEL_PM 1
+#endif
+
+/**
+ * @ingroup los_config
+ * Configuration item for priority of low-power task.
+ */
+#ifndef LOSCFG_KERNEL_PM_TASK_PTIORITY
+#define LOSCFG_KERNEL_PM_TASK_PTIORITY 1
+#endif
+
+/**
+ * @ingroup los_config
+ * Configuration item for stack size of low-power task.
+ */
+#ifndef LOSCFG_KERNEL_PM_TASK_STACKSIZE
+#define LOSCFG_KERNEL_PM_TASK_STACKSIZE 0x800
+#endif
+
+/**
+ * @ingroup los_config
+ * Configuration item for low power frame debug tailoring
+ */
+#ifndef LOSCFG_KERNEL_PM_DEBUG
+#define LOSCFG_KERNEL_PM_DEBUG 0
#endif
/**
diff --git a/kernel/include/los_sched.h b/kernel/include/los_sched.h
index b514edb3..a031ec3a 100644
--- a/kernel/include/los_sched.h
+++ b/kernel/include/los_sched.h
@@ -53,7 +53,7 @@ VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask);
UINT32 OsSchedSwtmrScanRegister(SchedScan func);
-VOID OsSchedUpdateExpireTime(UINT64 startTime);
+VOID OsSchedUpdateExpireTime(UINT64 startTime, BOOL timeUpdate);
VOID OsSchedTaskDeQueue(LosTaskCB *taskCB);
@@ -81,27 +81,64 @@ BOOL OsSchedTaskSwitch(VOID);
LosTaskCB *OsGetTopTask(VOID);
+UINT32 OsSchedRealSleepTimeSet(VOID (*func)(UINT64));
+
+VOID OsSchedTimerBaseReset(UINT64 currTime);
+
+/**
+ * @ingroup los_sched
+ * @brief Get the time, in nanoseconds, remaining before the next tick interrupt response.
+ *
+ * @par Description:
+ * This API is used to get the time, in nanoseconds, remaining before the next tick interrupt response.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval #time, in nanoseconds.
+ * @par Dependency:
+ * - los_sched.h: the header file that contains the API declaration.
+ * @see
+ */
+extern UINT64 LOS_SchedTickTimeoutNsGet(VOID);
+
+/**
+ * @ingroup los_sched
+ * @brief The system-provided tick interrupt handler.
+ *
+ * @par Description:
+ * This API is used to wake up a task that is blocked by time.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval None.
+ * @par Dependency:
+ * - los_sched.h: the header file that contains the API declaration.
+ * @see
+ */
extern VOID LOS_SchedTickHandler(VOID);
+/**
+ * @ingroup los_sched
+ * @brief Trigger a system dispatch.
+ *
+ * @par Description:
+ * This API is used to trigger a system dispatch.
+ *
+ * @attention None.
+ *
+ * @param None.
+ *
+ * @retval None.
+ * @par Dependency:
+ * - los_sched.h: the header file that contains the API declaration.
+ * @see
+ */
extern VOID LOS_Schedule(VOID);
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
-VOID OsSchedUpdateSleepTime(VOID);
-
-VOID OsSchedToSleep(VOID);
-
-typedef UINT32 (*SchedSleepInit)(VOID);
-
-typedef VOID (*SchedSleepStart)(UINT64);
-
-typedef VOID (*SchedSleepStop)(VOID);
-
-typedef UINT64 (*SchedSleepGetSleepTimeNs)(VOID);
-
-extern UINT32 LOS_SchedSleepInit(SchedSleepInit init, SchedSleepStart start,
- SchedSleepStop stop, SchedSleepGetSleepTimeNs getTime);
-#endif
-
#ifdef __cplusplus
#if __cplusplus
}
diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h
index de5072a4..15cb28c6 100644
--- a/kernel/include/los_task.h
+++ b/kernel/include/los_task.h
@@ -1636,6 +1636,8 @@ extern UINT32 OsGetAllTskInfo(VOID);
extern VOID *OsTskUserStackInit(VOID* stackPtr, VOID* userSP, UINT32 userStackSize);
+extern UINT32 OsPmEnterHandlerSet(VOID (*func)(BOOL));
+
#ifdef __cplusplus
#if __cplusplus
}
diff --git a/kernel/include/los_tick.h b/kernel/include/los_tick.h
index ea2bdc88..a11931f8 100644
--- a/kernel/include/los_tick.h
+++ b/kernel/include/los_tick.h
@@ -124,6 +124,12 @@ extern UINT64 LOS_SysCycleGet(VOID);
#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
+#define OS_SYS_CYCLE_TO_NS(cycle, freq) (((cycle) / (freq)) * OS_SYS_NS_PER_SECOND + \
+ ((cycle) % OS_SYS_CLOCK) * OS_SYS_NS_PER_SECOND / (freq))
+
+#define OS_SYS_NS_TO_CYCLE(time, freq) (((time) / OS_SYS_NS_PER_SECOND) * (freq) + \
+ (time % OS_SYS_NS_PER_SECOND) * (freq) / OS_SYS_NS_PER_SECOND)
+
/**
* @ingroup los_tick
* System time basic function error code: Null pointer.
diff --git a/kernel/src/los_init.c b/kernel/src/los_init.c
index a363db47..b5ec6cfe 100644
--- a/kernel/src/los_init.c
+++ b/kernel/src/los_init.c
@@ -62,6 +62,9 @@
#include "los_backtrace.h"
#endif
+#if (LOSCFG_KERNEL_PM == 1)
+#include "los_pm.h"
+#endif
/*****************************************************************************
Function : LOS_Reboot
@@ -191,6 +194,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID)
}
#endif
+#if (LOSCFG_KERNEL_PM == 1)
+ ret = OsPmInit();
+ if (ret != LOS_OK) {
+ PRINT_ERR("Pm init failed!\n");
+ return ret;
+ }
+#endif
+
#ifdef LOSCFG_TEST
//ret = los_TestInit();
//if (ret != LOS_OK) {
diff --git a/kernel/src/los_sched.c b/kernel/src/los_sched.c
index a7616fda..5d3f03bc 100644
--- a/kernel/src/los_sched.c
+++ b/kernel/src/los_sched.c
@@ -59,19 +59,17 @@ STATIC UINT32 g_queueBitmap;
STATIC UINT32 g_schedResponseID = 0;
STATIC UINT64 g_schedResponseTime = OS_SCHED_MAX_RESPONSE_TIME;
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
-typedef struct {
- SchedSleepInit init;
- SchedSleepStart start;
- SchedSleepStop stop;
- SchedSleepGetSleepTimeNs getTimeNs;
-} SchedSleep;
+STATIC VOID (*SchedRealSleepTimeSet)(UINT64) = NULL;
-STATIC BOOL g_schedSleepFlags = FALSE;
-STATIC UINT64 g_schedSleepTime;
-STATIC UINT64 g_schedEntrySleepTime;
-STATIC SchedSleep g_schedSleepCB;
-#endif
+UINT32 OsSchedRealSleepTimeSet(VOID (*func)(UINT64))
+{
+ if (func == NULL) {
+ return LOS_NOK;
+ }
+
+ SchedRealSleepTimeSet = func;
+ return LOS_OK;
+}
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
STATIC UINT64 g_schedTimerBase;
@@ -83,6 +81,14 @@ VOID OsSchedUpdateSchedTimeBase(VOID)
(VOID)HalGetTickCycle(&period);
g_schedTimerBase += period;
}
+
+VOID OsSchedTimerBaseReset(UINT64 currTime)
+{
+ LOS_ASSERT(currTime > g_schedTimerBase);
+
+ g_schedTimerBase = currTime;
+ g_schedResponseTime = OS_SCHED_MAX_RESPONSE_TIME;
+}
#endif
UINT64 OsGetCurrSchedTimeCycle(VOID)
@@ -124,7 +130,7 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime)
taskCB->startTime = currTime;
}
-STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, UINT64 taskEndTime)
+STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, UINT64 taskEndTime, BOOL timeUpdate)
{
UINT64 nextExpireTime = OsGetNextExpireTime(startTime);
UINT64 nextResponseTime;
@@ -141,15 +147,15 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
if ((g_schedResponseTime > nextExpireTime) && ((g_schedResponseTime - nextExpireTime) >= OS_CYCLE_PER_TICK)) {
nextResponseTime = nextExpireTime - startTime;
if (nextResponseTime > OS_TICK_RESPONSE_TIME_MAX) {
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- g_schedSleepTime = nextResponseTime - OS_CYCLE_PER_TICK;
-#endif
+ if (SchedRealSleepTimeSet != NULL) {
+ SchedRealSleepTimeSet(nextResponseTime);
+ }
nextResponseTime = OS_TICK_RESPONSE_TIME_MAX;
nextExpireTime = startTime + nextResponseTime;
} else if (nextResponseTime < OS_CYCLE_PER_TICK) {
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
- g_schedSleepTime = 0;
-#endif
+ if (SchedRealSleepTimeSet != NULL) {
+ SchedRealSleepTimeSet(0);
+ }
nextResponseTime = OS_CYCLE_PER_TICK;
nextExpireTime = startTime + nextResponseTime;
if (nextExpireTime >= g_schedResponseTime) {
@@ -170,12 +176,14 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
g_schedResponseTime = nextExpireTime;
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
- g_schedTimerBase = OsGetCurrSchedTimeCycle();
+ if (timeUpdate) {
+ g_schedTimerBase = OsGetCurrSchedTimeCycle();
+ }
#endif
HalSysTickReload(nextResponseTime);
}
-VOID OsSchedUpdateExpireTime(UINT64 startTime)
+VOID OsSchedUpdateExpireTime(UINT64 startTime, BOOL timeUpdate)
{
UINT64 endTime;
LosTaskCB *runTask = g_losTask.runTask;
@@ -186,7 +194,7 @@ VOID OsSchedUpdateExpireTime(UINT64 startTime)
} else {
endTime = OS_SCHED_MAX_RESPONSE_TIME;
}
- OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime);
+ OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, timeUpdate);
}
STATIC INLINE VOID OsSchedPriQueueEnHead(LOS_DL_LIST *priqueueItem, UINT32 priority)
@@ -450,7 +458,7 @@ VOID OsSchedStart(VOID)
g_schedResponseTime = OS_SCHED_MAX_RESPONSE_TIME;
g_schedResponseID = OS_INVALID;
- OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, newTask->startTime + newTask->timeSlice);
+ OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, newTask->startTime + newTask->timeSlice, TRUE);
PRINTK("Entering scheduler\n");
}
@@ -490,11 +498,31 @@ BOOL OsSchedTaskSwitch(VOID)
} else {
endTime = OS_SCHED_MAX_RESPONSE_TIME;
}
- OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime);
+ OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime, TRUE);
return isTaskSwitch;
}
+UINT64 LOS_SchedTickTimeoutNsGet(VOID)
+{
+ UINT32 intSave;
+ UINT64 responseTime;
+ UINT64 currTime;
+
+ intSave = LOS_IntLock();
+ responseTime = g_schedResponseTime;
+ currTime = OsGetCurrSchedTimeCycle();
+ LOS_IntRestore(intSave);
+
+ if (responseTime > currTime) {
+ responseTime = responseTime - currTime;
+ } else {
+ responseTime = 0; /* Tick interrupt already timeout */
+ }
+
+ return OS_SYS_CYCLE_TO_NS(responseTime, OS_SYS_CLOCK);
+}
+
VOID LOS_SchedTickHandler(VOID)
{
UINT64 currTime;
@@ -518,7 +546,7 @@ VOID LOS_SchedTickHandler(VOID)
} else {
currTime = OsGetCurrSchedTimeCycle();
OsTimeSliceUpdate(g_losTask.runTask, currTime);
- OsSchedUpdateExpireTime(currTime);
+ OsSchedUpdateExpireTime(currTime, TRUE);
}
LOS_IntRestore(intSave);
@@ -531,103 +559,6 @@ VOID LOS_Schedule(VOID)
}
}
-#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
-VOID OsSchedUpdateSleepTime(VOID)
-{
- UINT64 nextResponseTime;
- UINT64 currTime, realSleepTime;
- UINT32 intSave;
-
- if ((g_schedSleepFlags == FALSE) || (g_schedSleepCB.stop == NULL)) {
- return;
- }
-
- intSave = LOS_IntLock();
- if (g_schedSleepCB.getTimeNs != NULL) {
- realSleepTime = g_schedSleepCB.getTimeNs();
- realSleepTime = (realSleepTime / OS_SYS_NS_PER_SECOND) * OS_SYS_CLOCK +
- (realSleepTime % OS_SYS_NS_PER_SECOND) * OS_SYS_CLOCK / OS_SYS_NS_PER_SECOND;
- if (realSleepTime < g_schedSleepTime) {
- nextResponseTime = g_schedSleepTime - realSleepTime;
- } else {
- nextResponseTime = 0;
- }
-
-#if (LOSCFG_BASE_CORE_TICK_WTIMER == 1)
- currTime = HalGetTickCycle(NULL);
-#else
- g_schedTimerBase = g_schedEntrySleepTime + realSleepTime;
- currTime = g_schedTimerBase;
-#endif
- if (nextResponseTime > OS_TICK_RESPONSE_TIME_MAX) {
- nextResponseTime = OS_TICK_RESPONSE_TIME_MAX;
- } else if (nextResponseTime < OS_CYCLE_PER_TICK) {
- nextResponseTime = OS_CYCLE_PER_TICK;
- }
-
- g_schedResponseID = OS_INVALID;
- g_schedResponseTime = currTime + nextResponseTime;
- HalSysTickReload(nextResponseTime);
- g_schedSleepTime = 0;
- }
- g_schedSleepFlags = FALSE;
- g_schedSleepCB.stop();
- LOS_IntRestore(intSave);
-}
-
-VOID OsSchedToSleep(VOID)
-{
- UINT32 intSave;
- UINT64 sleepTime;
-
- if (g_schedSleepCB.start == NULL) {
- return;
- }
-
- if (g_schedSleepCB.getTimeNs != NULL) {
- sleepTime = (g_schedSleepTime / OS_SYS_CLOCK) * OS_SYS_NS_PER_SECOND +
- (g_schedSleepTime % OS_SYS_CLOCK) * OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK;
- if (sleepTime == 0) {
- return;
- }
-
- intSave = LOS_IntLock();
- HalTickLock();
- g_schedEntrySleepTime = OsGetCurrSchedTimeCycle();
- } else {
- intSave = LOS_IntLock();
- }
-
- g_schedSleepCB.start(sleepTime);
- g_schedSleepFlags = TRUE;
- LOS_IntRestore(intSave);
-}
-
-UINT32 LOS_SchedSleepInit(SchedSleepInit init, SchedSleepStart start,
- SchedSleepStop stop, SchedSleepGetSleepTimeNs getTime)
-{
- UINT32 ret;
-
- if ((init == NULL) && (start == NULL) && (stop == NULL)) {
- return LOS_NOK;
- }
-
- g_schedSleepCB.init = init;
- g_schedSleepCB.start = start;
- g_schedSleepCB.stop = stop;
- g_schedSleepCB.getTimeNs = getTime;
-
- if (g_schedSleepCB.init != NULL) {
- ret = g_schedSleepCB.init();
- if (ret != LOS_OK) {
- return ret;
- }
- }
-
- return LOS_OK;
-}
-#endif
-
#ifdef __cplusplus
#if __cplusplus
}
diff --git a/kernel/src/los_swtmr.c b/kernel/src/los_swtmr.c
index d7a257af..3171aa58 100644
--- a/kernel/src/los_swtmr.c
+++ b/kernel/src/los_swtmr.c
@@ -217,7 +217,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
#endif
OsAdd2SortLink(&swtmr->stSortList, currTime, swtmr->uwCount, OS_SORT_LINK_SWTMR);
if (LOS_TaskIsRunning()) {
- OsSchedUpdateExpireTime(currTime);
+ OsSchedUpdateExpireTime(currTime, TRUE);
}
}
@@ -248,7 +248,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr)
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
if (LOS_TaskIsRunning()) {
- OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle());
+ OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle(), TRUE);
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned = 0;
#endif
diff --git a/kernel/src/los_task.c b/kernel/src/los_task.c
index b1c2f76a..18ddf34d 100644
--- a/kernel/src/los_task.c
+++ b/kernel/src/los_task.c
@@ -45,7 +45,6 @@
#include "los_cpup.h"
#endif
-
/**
* @ingroup los_task
* @brief Convenience macro for bitwise operation of task module
@@ -102,6 +101,8 @@ LITE_OS_SEC_DATA_INIT LOS_DL_LIST g_losFreeTask;
LITE_OS_SEC_DATA_INIT LOS_DL_LIST g_taskRecyleList;
LITE_OS_SEC_BSS BOOL g_taskScheduled = FALSE;
+STATIC VOID (*PmEnter)(BOOL isIdle) = NULL;
+
#if (LOSCFG_BASE_CORE_TSK_MONITOR == 1)
TSKSWITCHHOOK g_pfnUsrTskSwitchHook = NULL;
#endif /* LOSCFG_BASE_CORE_TSK_MONITOR == 1 */
@@ -145,6 +146,16 @@ STATIC VOID OsRecyleFinishedTask(VOID)
LOS_IntRestore(intSave);
}
+UINT32 OsPmEnterHandlerSet(VOID (*func)(BOOL))
+{
+ if (func == NULL) {
+ return LOS_NOK;
+ }
+
+ PmEnter = func;
+ return LOS_OK;
+}
+
/*****************************************************************************
Function : OsIdleTask
Description : Idle task.
@@ -152,11 +163,16 @@ STATIC VOID OsRecyleFinishedTask(VOID)
Output : None
Return : None
*****************************************************************************/
-LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID)
+LITE_OS_SEC_TEXT VOID OsIdleTask(VOID)
{
while (1) {
OsRecyleFinishedTask();
- HalEnterSleep(OS_SYS_DEEP_SLEEP);
+
+ if (PmEnter != NULL) {
+ PmEnter(TRUE);
+ } else {
+ (VOID)HalEnterSleep();
+ }
}
}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h b/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h
index 252ab517..42c7745c 100644
--- a/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h
+++ b/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h
@@ -52,7 +52,6 @@ extern "C" {
#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
#define LOSCFG_BASE_CORE_TICK_WTIMER 1
-#define LOSCFG_BASE_CORE_SCHED_SLEEP 1
/*=============================================================================
Hardware interrupt module configuration
=============================================================================*/
diff --git a/targets/riscv_nuclei_gd32vf103_soc_gcc/OS_CONFIG/target_config.h b/targets/riscv_nuclei_gd32vf103_soc_gcc/OS_CONFIG/target_config.h
index 011edc46..f5a99707 100644
--- a/targets/riscv_nuclei_gd32vf103_soc_gcc/OS_CONFIG/target_config.h
+++ b/targets/riscv_nuclei_gd32vf103_soc_gcc/OS_CONFIG/target_config.h
@@ -52,7 +52,6 @@ extern "C" {
#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
#define LOSCFG_BASE_CORE_TICK_WTIMER 1
-#define LOSCFG_BASE_CORE_SCHED_SLEEP 1
/*=============================================================================
Hardware interrupt module configuration
=============================================================================*/
diff --git a/utils/los_error.h b/utils/los_error.h
index aa8b7de4..cc6acf04 100644
--- a/utils/los_error.h
+++ b/utils/los_error.h
@@ -204,6 +204,7 @@ enum LOS_MODULE_ID {
LOS_MOD_MUX = 0X1d,
LOS_MOD_CPUP = 0x1e,
LOS_MOD_HOOK = 0x1f,
+ LOS_MOD_PM = 0x20,
LOS_MOD_SHELL = 0x31,
LOS_MOD_BUTT
};