!358 feat: L1支持低功耗投票框架

Merge pull request !358 from zhushengle/pm_v
This commit is contained in:
openharmony_ci 2021-06-25 00:26:41 +00:00 committed by Gitee
commit 12577eade5
10 changed files with 623 additions and 1 deletions

View File

@ -45,6 +45,8 @@ extern "C" {
extern spinlock_t procfsLock;
extern bool procfsInit;
void ProcPmInit(void);
void ProcVmmInit(void);
void ProcProcessInit(void);

View File

@ -0,0 +1,178 @@
/*
* 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 <sys/statfs.h>
#include <sys/mount.h>
#include "proc_fs.h"
#include "internal.h"
#ifdef LOSCFG_KERNEL_PM
#include "los_pm.h"
static int PowerLockWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos)
{
(void)pf;
(void)count;
(void)ppos;
return -LOS_PmLockRequest(buf);
}
static int PowerLockRead(struct SeqBuf *m, void *v)
{
(void)v;
LOS_PmLockInfoShow(m);
return 0;
}
static const struct ProcFileOperations PowerLock = {
.write = PowerLockWrite,
.read = PowerLockRead,
};
static int PowerUnlockWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos)
{
(void)pf;
(void)count;
(void)ppos;
return -LOS_PmLockRelease(buf);
}
static const struct ProcFileOperations PowerUnlock = {
.write = PowerUnlockWrite,
.read = PowerLockRead,
};
static int PowerModeWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos)
{
(void)pf;
(void)count;
(void)ppos;
if (buf == NULL) {
return 0;
}
if (strcmp(buf, "normal") != 0) {
return LOS_NOK;
}
return 0;
}
static int PowerModeRead(struct SeqBuf *m, void *v)
{
(void)v;
LosBufPrintf(m, "normal \n");
return 0;
}
static const struct ProcFileOperations PowerMode = {
.write = PowerModeWrite,
.read = PowerModeRead,
};
static int PowerCountRead(struct SeqBuf *m, void *v)
{
(void)v;
UINT32 count = LOS_PmLockCountGet();
LosBufPrintf(m, "%u\n", count);
return 0;
}
static const struct ProcFileOperations PowerCount = {
.write = NULL,
.read = PowerCountRead,
};
#define POWER_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)
#define OS_POWER_PRIVILEGE 7
void ProcPmInit(void)
{
struct ProcDirEntry *power = CreateProcEntry("power", S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH, NULL);
if (power == NULL) {
PRINT_ERR("create /proc/power error!\n");
return;
}
power->uid = OS_POWER_PRIVILEGE;
power->gid = OS_POWER_PRIVILEGE;
struct ProcDirEntry *mode = CreateProcEntry("power/power_mode", POWER_FILE_MODE, NULL);
if (mode == NULL) {
PRINT_ERR("create /proc/power/power_mode error!\n");
goto FREE_POWER;
}
mode->procFileOps = &PowerMode;
mode->uid = OS_POWER_PRIVILEGE;
mode->gid = OS_POWER_PRIVILEGE;
struct ProcDirEntry *lock = CreateProcEntry("power/power_lock", POWER_FILE_MODE, NULL);
if (lock == NULL) {
PRINT_ERR("create /proc/power/power_lock error!\n");
goto FREE_MODE;
}
lock->procFileOps = &PowerLock;
lock->uid = OS_POWER_PRIVILEGE;
lock->gid = OS_POWER_PRIVILEGE;
struct ProcDirEntry *unlock = CreateProcEntry("power/power_unlock", POWER_FILE_MODE, NULL);
if (unlock == NULL) {
PRINT_ERR("create /proc/power/power_unlock error!\n");
goto FREE_LOCK;
}
unlock->procFileOps = &PowerUnlock;
unlock->uid = OS_POWER_PRIVILEGE;
unlock->gid = OS_POWER_PRIVILEGE;
struct ProcDirEntry *count = CreateProcEntry("power/power_count", S_IRUSR | S_IRGRP | S_IROTH, NULL);
if (count == NULL) {
PRINT_ERR("create /proc/power/power_count error!\n");
goto FREE_UNLOCK;
}
count->procFileOps = &PowerCount;
count->uid = OS_POWER_PRIVILEGE;
count->gid = OS_POWER_PRIVILEGE;
return;
FREE_UNLOCK:
ProcFreeEntry(unlock);
FREE_LOCK:
ProcFreeEntry(lock);
FREE_MODE:
ProcFreeEntry(mode);
FREE_POWER:
ProcFreeEntry(power);
return;
}
#endif

View File

@ -66,6 +66,9 @@ void ProcFsInit(void)
ProcKernelTraceInit();
ProcFsCacheInit();
ProcFdInit();
#ifdef LOSCFG_KERNEL_PM
ProcPmInit();
#endif
}
LOS_MODULE_INIT(ProcFsInit, LOS_INIT_LEVEL_KMOD_EXTENDED);

View File

@ -89,6 +89,13 @@ config KERNEL_DYNLOAD
help
If you wish to build LiteOS with support for dynamic load.
config KERNEL_PM
bool "Enable Power Management"
default y
depends on KERNEL_EXTKERNEL
help
If you wish to build LiteOS with support for power management.
config ASLR
bool "Enable Address Space Layout Randomization"
default n

View File

@ -0,0 +1,42 @@
# 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 $(LITEOSTOPDIR)/config.mk
MODULE_NAME := $(notdir $(shell pwd))
LOCAL_SRCS := $(wildcard *.c)
LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/kernel/base/include \
-I $(LITEOSTOPDIR)/kernel/extended/include \
-I $(LITEOSTOPDIR)/arch/arm/include
LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS)
include $(MODULE)

View File

@ -0,0 +1,238 @@
/*
* 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_pri.h"
#include "los_init.h"
#include "los_memory.h"
#include "los_spinlock.h"
#include "los_mp.h"
#ifdef LOSCFG_KERNEL_PM
#define PM_INFO_SHOW(seqBuf, arg...) do { \
if (seqBuf != NULL) { \
(void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \
} else { \
PRINTK(arg); \
} \
} while (0)
#define OS_PM_LOCK_MAX 0xFFFFU
#define OS_PM_LOCK_NAME_MAX 28
typedef UINT32 (*Suspend)(VOID);
typedef struct {
CHAR name[OS_PM_LOCK_NAME_MAX];
UINT32 count;
LOS_DL_LIST list;
} OsPmLockCB;
typedef struct {
LOS_SysSleepEnum mode;
UINT16 lock;
LOS_DL_LIST lockList;
} LosPmCB;
STATIC LosPmCB g_pmCB;
STATIC SPIN_LOCK_INIT(g_pmSpin);
LOS_SysSleepEnum LOS_PmModeGet(VOID)
{
LOS_SysSleepEnum mode;
LosPmCB *pm = &g_pmCB;
LOS_SpinLock(&g_pmSpin);
mode = pm->mode;
LOS_SpinUnlock(&g_pmSpin);
return mode;
}
UINT32 LOS_PmLockCountGet(VOID)
{
UINT16 count;
LosPmCB *pm = &g_pmCB;
LOS_SpinLock(&g_pmSpin);
count = pm->lock;
LOS_SpinUnlock(&g_pmSpin);
return (UINT32)count;
}
VOID LOS_PmLockInfoShow(struct SeqBuf *m)
{
UINT32 intSave;
LosPmCB *pm = &g_pmCB;
OsPmLockCB *lock = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
intSave = LOS_IntLock();
while (list != head) {
lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
PM_INFO_SHOW(m, "%-30s%5u\n\r", lock->name, lock->count);
list = list->pstNext;
}
LOS_IntRestore(intSave);
return;
}
UINT32 LOS_PmLockRequest(const CHAR *name)
{
INT32 len;
errno_t err;
LosPmCB *pm = &g_pmCB;
OsPmLockCB *listNode = NULL;
OsPmLockCB *lock = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
if (name == NULL) {
return LOS_EINVAL;
}
if (OS_INT_ACTIVE) {
return LOS_EINTR;
}
len = strlen(name);
if (len == 0) {
return LOS_EINVAL;
}
LOS_SpinLock(&g_pmSpin);
if (pm->lock >= OS_PM_LOCK_MAX) {
LOS_SpinUnlock(&g_pmSpin);
return LOS_EINVAL;
}
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_SpinUnlock(&g_pmSpin);
return LOS_ENOMEM;
}
err = memcpy_s(lock->name, OS_PM_LOCK_NAME_MAX, name, len + 1);
if (err != EOK) {
LOS_SpinUnlock(&g_pmSpin);
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lock);
return err;
}
lock->count = 1;
LOS_ListTailInsert(head, &lock->list);
} else if (lock->count < OS_PM_LOCK_MAX) {
lock->count++;
}
pm->lock++;
LOS_SpinUnlock(&g_pmSpin);
return LOS_OK;
}
UINT32 LOS_PmLockRelease(const CHAR *name)
{
LosPmCB *pm = &g_pmCB;
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_EINVAL;
}
if (OS_INT_ACTIVE) {
return LOS_EINTR;
}
LOS_SpinLock(&g_pmSpin);
if (pm->lock == 0) {
LOS_SpinUnlock(&g_pmSpin);
return LOS_EINVAL;
}
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_SpinUnlock(&g_pmSpin);
return LOS_EACCES;
} else if (lock->count > 0) {
lock->count--;
if (lock->count == 0) {
LOS_ListDelete(&lock->list);
lockFree = lock;
}
}
pm->lock--;
LOS_SpinUnlock(&g_pmSpin);
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
return LOS_OK;
}
UINT32 OsPmInit(VOID)
{
LosPmCB *pm = &g_pmCB;
(VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
pm->mode = LOS_SYS_NORMAL_SLEEP;
LOS_ListInit(&pm->lockList);
return LOS_OK;
}
LOS_MODULE_INIT(OsPmInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
#endif

140
kernel/include/los_pm.h Normal file
View File

@ -0,0 +1,140 @@
/*
* 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_typedef.h"
#include "los_list.h"
#include "los_seq_buf.h"
#include "los_errno.h"
typedef enum {
LOS_SYS_NORMAL_SLEEP = 0,
LOS_SYS_LIGHT_SLEEP,
LOS_SYS_DEEP_SLEEP,
LOS_SYS_SHUTDOWN,
} LOS_SysSleepEnum;
/**
* @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:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see
*/
LOS_SysSleepEnum LOS_PmModeGet(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 Number of locks held.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see
*/
UINT32 LOS_PmLockCountGet(VOID);
/**
* @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:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @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:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRequest
*/
UINT32 LOS_PmLockRelease(const CHAR *name);
/**
* @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 m [IN] .
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRequest
*/
VOID LOS_PmLockInfoShow(struct SeqBuf *m);
#endif

View File

@ -160,6 +160,10 @@ typedef size_t BOOL;
#define LOS_EACCES 13
#endif
#ifndef LOS_EFAULT
#define LOS_EFAULT 14
#endif
#ifndef LOS_EBUSY
#define LOS_EBUSY 16
#endif

View File

@ -113,7 +113,8 @@ LITEOS_TABLES_EXTEND_LDFLAGS := \
-ui2c_read_shellcmd \
-ussp_read_shellcmd \
-uuart_config_shellcmd\
-uusb_debug_shellcmd
-uusb_debug_shellcmd \
-uOsPmInit
LITEOS_TABLES_KERNEL_INIT_LDFLAGS := \
-uOsTraceInit \

View File

@ -219,6 +219,13 @@ ifeq ($(LOSCFG_KERNEL_PIPE), y)
LIB_SUBDIRS += kernel/extended/pipes
LITEOS_PIPE_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/pipes
endif
ifeq ($(LOSCFG_KERNEL_PM), y)
LITEOS_BASELIB += -lpower
LIB_SUBDIRS += kernel/extended/power
LITEOS_PIPE_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/power
endif
################################### Kernel Option End ################################
#################################### Lib Option Begin ###############################