!169 feat: L0支持低功耗投票框架

Merge pull request !169 from zhushengle/PM
This commit is contained in:
openharmony_ci
2021-06-22 11:55:22 +00:00
committed by Gitee
35 changed files with 1239 additions and 272 deletions

View File

@@ -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) {

View File

@@ -57,19 +57,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;
@@ -81,6 +79,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)
@@ -122,7 +128,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;
@@ -139,15 +145,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) {
@@ -168,12 +174,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;
@@ -184,7 +192,7 @@ VOID OsSchedUpdateExpireTime(UINT64 startTime)
} else {
endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_CYCLE_PER_TICK;
}
OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime);
OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, timeUpdate);
}
STATIC INLINE VOID OsSchedPriQueueEnHead(LOS_DL_LIST *priqueueItem, UINT32 priority)
@@ -448,7 +456,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");
}
@@ -488,11 +496,31 @@ BOOL OsSchedTaskSwitch(VOID)
} else {
endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_CYCLE_PER_TICK;
}
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;
@@ -516,7 +544,7 @@ VOID LOS_SchedTickHandler(VOID)
} else {
currTime = OsGetCurrSchedTimeCycle();
OsTimeSliceUpdate(g_losTask.runTask, currTime);
OsSchedUpdateExpireTime(currTime);
OsSchedUpdateExpireTime(currTime, TRUE);
}
LOS_IntRestore(intSave);
@@ -529,103 +557,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
}

View File

@@ -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

View File

@@ -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();
}
}
}