Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OS Managed Power Management framework #9416

Merged
merged 3 commits into from
Aug 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions arch/arm/soc/nordic_nrf/nrf52/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,21 @@ void _sys_soc_power_state_post_ops(enum power_states state)
break;
}
}

bool _sys_soc_is_valid_power_state(enum power_states state)
{
switch (state) {
case SYS_POWER_STATE_CPU_LPS:
case SYS_POWER_STATE_CPU_LPS_1:
#if defined(CONFIG_SYS_POWER_DEEP_SLEEP)
case SYS_POWER_STATE_DEEP_SLEEP:
#endif
return true;
break;
default:
SYS_LOG_DBG("Unsupported State\n");
break;
}

return false;
}
5 changes: 5 additions & 0 deletions arch/arm/soc/nordic_nrf/nrf52/soc_power.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ enum power_states {
*/
void _sys_soc_set_power_state(enum power_states state);

/**
* @brief Check a low power state is supported by SoC
*/
bool _sys_soc_is_valid_power_state(enum power_states state);

/**
* @brief Do any SoC or architecture specific post ops after low power states.
*/
Expand Down
23 changes: 23 additions & 0 deletions kernel/Kconfig.power_mgmt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@ menuconfig SYS_POWER_MANAGEMENT
timer is due to expire.

if SYS_POWER_MANAGEMENT
choice POWER_MANAGEMENT_CONTROL
prompt "Power Management Control"
default PM_CONTROL_APP
help
Select the Application managed or OS managed power saving
mechanism.

config PM_CONTROL_APP
bool
prompt "Handled at Application level"
help
This option enbles the Application to handle all the Power
Management flows for the platform.

config PM_CONTROL_OS
bool
prompt "Handle at OS level"
help
This option allows the OS to handle all the Power
Management flows for the platform.

endchoice # POWER_MANAGEMENT_CONTROL

config SYS_POWER_LOW_POWER_STATE
bool "Low power state"
depends on SYS_POWER_LOW_POWER_STATE_SUPPORTED
Expand Down
10 changes: 10 additions & 0 deletions samples/subsys/power/power.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. _power_management-samples:

Power Management Samples
########################

.. toctree::
:maxdepth: 1
:glob:

**/*
6 changes: 6 additions & 0 deletions samples/subsys/power/power_mgr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.8.2)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
79 changes: 79 additions & 0 deletions samples/subsys/power/power_mgr/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.. _os-power-mgr-sample:

OS Power management demo
###########################

Overview
********

This sample demonstrates OS managed power saving mechanism through the sample
application which will periodically go sleep there by invoking the idle thread
which will call the _sys_soc_suspend() to enter into low power states. The Low
Power state will be selected based on the next timeout event.

Requirements
************

This application uses nrf52 DK board for the demo.

Building, Flashing and Running
******************************

.. zephyr-app-commands::
:zephyr-app: samples/subsys/power/power_mgr
:board: nrf52_pca10040
:goals: build flash
:compact:

Running:

1. Open UART terminal.
2. Power Cycle Device.
3. Device will enter into Low Power Modes periodically.


Sample Output
=================
nrf52 core output
-----------------

.. code-block:: console
***OS Power Management Demo on arm****
Demo Description
Application creates Idleness, Due to which System Idle Thread is
scheduled and it enters into various Low Power States.
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 6000 msec -->
Entering Low Power state (0)
Entering Low Power state (0)
Entering Low Power state (0)
Entering Low Power state (0)
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 11000 msec -->
Entering Low Power state (1)
Entering Low Power state (1)
Entering Low Power state (1)
Entering Low Power state (1)
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 6000 msec -->
Entering Low Power state (0)
Entering Low Power state (0)
Entering Low Power state (0)
Entering Low Power state (0)
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 11000 msec -->
Entering Low Power state (1)
Entering Low Power state (1)
Entering Low Power state (1)
Entering Low Power state (1)
OS managed Power Management Test completed
13 changes: 13 additions & 0 deletions samples/subsys/power/power_mgr/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_LOW_POWER_STATE=y
CONFIG_SYS_POWER_DEEP_SLEEP=y
CONFIG_DEVICE_POWER_MANAGEMENT=y
CONFIG_TICKLESS_IDLE=y

CONFIG_PM_CONTROL_OS=y
CONFIG_PM_CONTROL_OS_LPS=y
CONFIG_PM_LPS_MIN_RES=5
CONFIG_PM_CONTROL_OS_LPS_1=y
CONFIG_PM_LPS_1_MIN_RES=10
CONFIG_PM_CONTROL_OS_DEEP_SLEEP=y
CONFIG_PM_DEEP_SLEEP_MIN_RES=60
16 changes: 16 additions & 0 deletions samples/subsys/power/power_mgr/prj_tickless.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CONFIG_NUM_COOP_PRIORITIES=29
CONFIG_NUM_PREEMPT_PRIORITIES=40
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_LOW_POWER_STATE=y
CONFIG_SYS_POWER_DEEP_SLEEP=y
CONFIG_DEVICE_POWER_MANAGEMENT=y
CONFIG_TICKLESS_KERNEL=y
CONFIG_TICKLESS_IDLE=y

CONFIG_PM_CONTROL_OS=y
CONFIG_PM_CONTROL_OS_LPS=y
CONFIG_PM_LPS_MIN_RES=5
CONFIG_PM_CONTROL_OS_LPS_1=y
CONFIG_PM_LPS_1_MIN_RES=10
CONFIG_PM_CONTROL_OS_DEEP_SLEEP=y
CONFIG_PM_DEEP_SLEEP_MIN_RES=60
6 changes: 6 additions & 0 deletions samples/subsys/power/power_mgr/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sample:
name: OS managed Power Management Sample
tests:
ospm.low_power_state:
platform_whitelist: nrf52840_pca10056 nrf52_pca10040
tags: power
61 changes: 61 additions & 0 deletions samples/subsys/power/power_mgr/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <power.h>
#include <soc_power.h>
#include <misc/printk.h>
#include <string.h>
#include <board.h>
#include <device.h>
#include <gpio.h>

#define SECONDS_TO_SLEEP 1

#define BUSY_WAIT_DELAY_US (10 * 1000000)

#define LPS_STATE_ENTER_TO ((CONFIG_PM_LPS_MIN_RES + 1) * 1000)
#define LPS1_STATE_ENTER_TO ((CONFIG_PM_LPS_1_MIN_RES + 1) * 1000)

#define DEMO_DESCRIPTION \
"Demo Description\n" \
"Application creates Idleness, Due to which System Idle Thread is\n"\
"scheduled and it enters into various Low Power States.\n"\

void sys_pm_notify_lps_entry(enum power_states state)
{
printk("Entering Low Power state (%d)\n", state);
}

void sys_pm_notify_lps_exit(enum power_states state)
{
printk("Entering Low Power state (%d)\n", state);
}

/* Application main Thread */
void main(void)
{
printk("\n\n***OS Power Management Demo on %s****\n", CONFIG_ARCH);
printk(DEMO_DESCRIPTION);

for (int i = 1; i <= 4; i++) {
printk("\n<-- App doing busy wait for 10 Sec -->\n");
k_busy_wait(BUSY_WAIT_DELAY_US);

/* Create Idleness to make Idle thread run */
if ((i % 2) == 0) {
printk("\n<-- App going to sleep for %d msec -->\n",
LPS1_STATE_ENTER_TO);
k_sleep(LPS1_STATE_ENTER_TO);
} else {
printk("\n<-- App going to sleep for %d msec -->\n",
LPS_STATE_ENTER_TO);
k_sleep(LPS_STATE_ENTER_TO);
}
}

printk("OS managed Power Management Test completed\n");
}
1 change: 1 addition & 0 deletions subsys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ add_subdirectory_ifdef(CONFIG_USB usb)
add_subdirectory(random)
add_subdirectory(storage)
add_subdirectory_ifdef(CONFIG_SETTINGS settings)
add_subdirectory_ifdef(CONFIG_PM_CONTROL_OS power)
2 changes: 2 additions & 0 deletions subsys/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ source "subsys/storage/Kconfig"
source "subsys/settings/Kconfig"

source "subsys/app_memory/Kconfig"

source "subsys/power/Kconfig"
5 changes: 5 additions & 0 deletions subsys/power/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
zephyr_sources(
power.c
policy.c
device.c
)
88 changes: 88 additions & 0 deletions subsys/power/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

if PM_CONTROL_OS
menu "OS Power Management"

if SYS_POWER_LOW_POWER_STATE
config PM_CONTROL_OS_LPS
bool "Platform supports LPS"
help
Select this option if SoC support LPS state.

if PM_CONTROL_OS_LPS
config PM_LPS_MIN_RES
int "LPS minimum residency"
default 5
help
Minimum residency in ticks to enter LPS state.
endif

config PM_CONTROL_OS_LPS_1
bool "Platform supports LPS_1"
help
Select this option if SoC support LPS_1 state.

if PM_CONTROL_OS_LPS_1
config PM_LPS_1_MIN_RES
int "LPS_1 minimum residency"
default 10
help
Minimum residency in ticks to enter LPS_1 state.
endif

config PM_CONTROL_OS_LPS_2
bool "Platform supports LPS_2"
help
Select this option if SoC support LPS_2 state.

if PM_CONTROL_OS_LPS_2
config PM_LPS_2_MIN_RES
int "LPS_2 minimum residency"
default 30
help
Minimum residency in ticks to enter LPS_2 state.
endif
endif # SYS_POWER_LOW_POWER_STATE

if SYS_POWER_DEEP_SLEEP
config PM_CONTROL_OS_DEEP_SLEEP
bool "Platform supports DEEP_SLEEP"
help
Select this option if SoC support DEEP_SLEEP state.

if PM_CONTROL_OS_DEEP_SLEEP
config PM_DEEP_SLEEP_MIN_RES
int "DEEP_SLEEP minimum residency"
default 60
help
Minimum residency in ticks to enter DEEP_SLEEP state.
endif

config PM_CONTROL_OS_DEEP_SLEEP_1
bool "Platform supports DEEP_SLEEP_1"
help
Select this option if SoC support DEEP_SLEEP_1 state.

if PM_CONTROL_OS_DEEP_SLEEP_1
config PM_DEEP_SLEEP_1_MIN_RES
int "DEEP_SLEEP_1 minimum residency"
default 90
help
Minimum residency in ticks to enter DEEP_SLEEP_1 state.
endif

config PM_CONTROL_OS_DEEP_SLEEP_2
bool "Platform supports DEEP_SLEEP_2"
help
Select this option if SoC support DEEP_SLEEP_2 state.

if PM_CONTROL_OS_DEEP_SLEEP_2
config PM_DEEP_SLEEP_2_MIN_RES
int "DEEP_SLEEP_2 minimum residency"
default 120
help
Minimum residency in ticks to enter DEEP_SLEEP_2 state.
endif
endif # PM_CONTROL_OS_DEEP_SLEEP

endmenu
endif # PM_CONTROL_OS
Loading