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

Conversation

ramakrishnapallala
Copy link

@ramakrishnapallala ramakrishnapallala commented Aug 14, 2018

arch: arm: nordic_nrf: Add an API to check for valid PM state
subsys: power: Add support for OS managed Power Management framework
samples: subsys: Add sample app to demo OS managed PM

Fixes #8255

@codecov-io
Copy link

codecov-io commented Aug 14, 2018

Codecov Report

Merging #9416 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #9416   +/-   ##
=======================================
  Coverage   52.15%   52.15%           
=======================================
  Files         212      212           
  Lines       25916    25916           
  Branches     5582     5582           
=======================================
  Hits        13517    13517           
  Misses      10149    10149           
  Partials     2250     2250

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 469bd39...7f6d3e5. Read the comment docs.

@carlescufi carlescufi requested a review from pizi-nordic August 14, 2018 08:50
#if defined(CONFIG_SYS_POWER_DEEP_SLEEP)
case SYS_POWER_STATE_DEEP_SLEEP:
#endif
lps_flag = true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just do return true; here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes will do.

lps_flag = true;
break;
default:
lps_flag = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just do return false; here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, will do.

transparent to devices. SOC and devices do not lose context in this Mode.
SOC supports the following two Low Power states :

A. CONSTANT LATENCY LOW POWER MODE : This Low Power State triggers CONSTLAT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that presented approach does not fit well into nRF5x architecture.
These SoCs have only 2 global states: Running and System OFF.

All other power management depends on the peripherals configuration. Mentioned 16MHz clock is requested when there is an peripheral depending on it. For example, it could be turned on by SPI when data transfer is performed or by enabling constant latency mode in PPI.

There is one exception from this rule: Software could select different clocks sources for so called high frequency and low frequency clocks. In both cases clock could came from crystal oscillator or RC oscillator. Usually this is done basing on simple rules:

  • If you need precise high frequency clock use crystal oscillator. Otherwise, you should stick on RC oscillator as it requires less power. For example stable high frequency clock is needed for stable carrier in radio peripheral. Depending on application it could be also turned on when precise time measurement is needed or stable timing is required on external interfaces (UART, PWM, I2S, PDM etc.)

  • You can save few cents from BoM (and release 2 GPIO pins) if you will use RC oscillator for a low frequency clock. However if you need low power or precise timing in peripherals running on 32kHz clock, you should use crystal oscillator.

As you see, there is no way to define "one fit all" power management approach. IMHO we should focus on good interface to peripheral power state management, which will allow application to select most suitable power management scheme.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pizi-nordic this is sample application documentation which i reused from existing sample. I will double check and fix the gaps.

Also on the PM states, from the documentation i saw that the nrf5x has support for two active power saving states (constant latency mode and low power mode).

The idea is to support pluggable PM policies based on the target application, in this base PR, I have added a simple policy to demonstrate the overall flows.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you referring the "Sub power modes" in http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html ?

If so, you see that mentioned power modes only affect PPI interconnect delay and CPU wakeup time. Changing these settings based on predicted sleep time, which is done in the example, is not a thing which we can recommend as these settings are in fact driven by the real-time requirements of application (we might break operation of PPI-based solutions relying on constant event latency if we switch to low power mode in runtime).

Despite of the fact, that this feature is a bit hard to show in nRF5x family, I think, that OS-level power management is a important feature which have to be implemented in Zephyr.

#include <soc.h>
#include <soc_power.h>

#define SYS_LOG_LEVEL CONFIG_SYS_LOG_PM_LEVEL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO new code should use new logger.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok will fix it.

config PM_CONTROL_OS_LPS
bool "Platfrom supports LPS"
help
This is the maximum number of bytes that the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the help string correct?
(please also look on the items below)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy paste error, will fix it.

* and clock domain dependencies.
*/
#ifdef CONFIG_SOC_SERIES_NRF52X
#define CONFIG_MAX_PM_DEVICES 15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO we should be not forced to count devices on board.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok will consider using the device list itself.

* device in the device list is busy as shown below :
* if(device_busy_check(&device_list[idx])) {do something}
*/
device_retval[i] = device_set_power_state(&pm_device_list[idx],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some devices (especially external to the chip) need several ms to enter deeps sleep state.
Are we going to block here waiting for each device on the list?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At present state of things, we will have to wait for the device suspend/resume to return because we cannot enter/exit SoC low power states without properly managing device PM.

In future, we will have support for dynamic device PM based on device idle status and can optimize the logic here to speed up things.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, that until blocking still is there, this feature will be not really usable in real-word applications.

if (!device_retval[i]) {
int idx = device_ordered_list[i];

device_set_power_state(&pm_device_list[idx],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above also applies here. I seen an I2C gyroscope chip which needed more than 80ms to wake up.
If we perform device wake-up synchronously, then timing of that operation might be not acceptable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this kind of complexity can be handled in the driver itself, for example, on resume driver can submit worker to do the actual wake up and handle the device status accordingly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. This will also make the sleep state longer saving more time. What about applications which need small latency?

}
}

if (is_core_dev) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, that this approach is too simple. For example the external device could be connected through I2C. Then we cannot disable I2C before disabling this external device.

There also might be a bit more complex dependencies: For example one of audio codec I used was connected through I2C, but for its operation needed clock derived form I2S stream. As result in order to communicate with such device we had to start I2S streaming (with silence as a content), then configure codec using I2C and then start transmitting real audio data.

I think that we should be able to handle situation described in the first example (as the second is a bit extreme). Information about dependencies could be obtained from device tree, especially if take care of describing there things like clock tree.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you pointed rightly, we need to use device tree here to handle the device dependencies which will come as incremental changes in the upcoming patches.

@@ -0,0 +1,92 @@
.. _nrf52-power-mgr-sample:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it's a copy of an existing sample documentation with no obvious changes (including the title): /samples/boards/nrf52/power_mgr/README.rst. The doc build complained that the label at the top of the doc here was the same as another document.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes David, will fix it.

******************************

.. zephyr-app-commands::
:zephyr-app: samples/boards/nrf52/power_mgr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and the sample app you're running is in another folder, not the one with this documentation in it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok will fix it.

Add an API _sys_soc_is_valid_power_state to check if a PM state
is valid or not.

Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
@ramakrishnapallala ramakrishnapallala force-pushed the pwr-mgmt-fw branch 2 times, most recently from 4086eba to 97ead6d Compare August 16, 2018 05:16
@ramakrishnapallala
Copy link
Author

@pizi-nordic I have addressed all your comments except the following:

MAX_DEVICE_NUM macro usages => This I will remove while adding device dependency logic based DT.

SYS_LOG: I looked at the ./doc/subsystems/logging/logger.rst but an example in kernel or driver code will be really helpful.

@ramakrishnapallala
Copy link
Author

@pizi-nordic @dbkinder I have addressed your comments and updated the PR, please have a look.

@ramakrishnapallala
Copy link
Author

@dbkinder I am getting following warning:

/home/buildslave/src/github.com/zephyrproject-rtos/zephyr/doc/_build/rst/doc/samples/subsys/power/power_mgr/README.rst: WARNING: document isn't included in any toctree

How to fix this?

@nashif
Copy link
Member

nashif commented Aug 20, 2018

How to fix this?

diff --git a/samples/subsys/power/power.rst b/samples/subsys/power/power.rst
new file mode 100644
index 0000000000..e1dd2cc6ee
--- /dev/null
+++ b/samples/subsys/power/power.rst
@@ -0,0 +1,10 @@
+.. _power_management-samples:
+
+Power Management Samples
+########################
+
+.. toctree::
+   :maxdepth: 1
+   :glob:
+
+   **/*

extern void sys_pm_create_device_list(void);

/**
* @brief Function to supend the devices in PM device list
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick - spelling mistake in suspend

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix it.

#else
#define SECS_TO_TICKS 100
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the ticks configurable? So, shouldn't you use a macro function to address it here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, will fix it.

Ramakrishna Pallala added 2 commits August 21, 2018 19:45
Add support for OS managed Power Management framework for Zephyr
under 'subsys/power'. This framework takes care of implementing
the _sys_soc_suspend/_sys_soc_resume API's, a PM policy based on
SoC Low Power residencies and also provides necessary API's to
do devices suspend and resume.

Also add necessary changes to support the existing Application
managed Power Management framework.

Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
Add a sample application to demonstrate OS managed
Power Management framework.

Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
@ramakrishnapallala ramakrishnapallala changed the title [RFC] OS Managed Power Management framework OS Managed Power Management framework Aug 21, 2018
@pizi-nordic
Copy link
Collaborator

SYS_LOG: I looked at the ./doc/subsystems/logging/logger.rst but an example in kernel or driver code will be really helpful.

Please look at #8816. I think that this is the most comprehensive example. There are also few PRs which are smaller (like #9361), but do not show all features.

@nashif
Copy link
Member

nashif commented Aug 21, 2018

@pizi-nordic are you ok with the changes otherwise? I think the PR was changed to use new logging subsystem already and we can further optimize the usage in the stabilisation period after this gets merged as part of 1.13

@nashif nashif dismissed stale reviews from dbkinder and pizi-nordic August 21, 2018 15:16

addressed

@pizi-nordic
Copy link
Collaborator

@pdunaj: FYI

@pizi-nordic
Copy link
Collaborator

pizi-nordic commented Aug 21, 2018

@nashif: The biggest issue what I see is bonding of CPU/PPI latency mode to the predicted sleep time. IMHO we should completely remove code which alters this setting from the nrf52/power.c.

I assume that rest of the pointed things will be solved later in subsequent PRs, so I have no problem with them.

PS: I see that fact that I answered to comments before I looked into the code caused some misunderstanding. I apologize for that.

#ifdef CONFIG_TICKLESS_KERNEL
#define SECS_TO_TICKS CONFIG_TICKLESS_KERNEL_TIME_UNIT_IN_MICRO_SECS
#else
#define SECS_TO_TICKS CONFIG_SYS_CLOCK_TICKS_PER_SEC
Copy link
Collaborator

@pizi-nordic pizi-nordic Aug 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such tick <-> time conversion is imprecise on some SoCs (especially nRF5x).
If you need a more precise timing, please use __ticks_to_ms() and _ms_to_ticks(). If not, this is OK.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pizi-nordic, for now, I will leave it like that. I am taking a note of this point and account this in my future changes.

@ramakrishnapallala
Copy link
Author

ramakrishnapallala commented Aug 22, 2018

@pizi-nordic
"The biggest issue what I see is bonding of CPU/PPI latency mode to the predicted sleep time. IMHO we should completely remove code which alters this setting from the nrf52/power.c."

_sys_soc_set_power_state from nrf52/power.c is only offering a mechanism to enter different power states(SYS_POWER_STATE_CPU_LPS/SYS_POWER_STATE_CPU_LPS_1) and does not have any info on power state residency or latency requirement. It is the PM policy which is making decisions on which PM state to enter through _sys_soc_suspend which is being defined by the application in the current code. The proposed changes are built on top of them.

As per the proposed changes, the application designer or developer has to define a PM policy which suits his requirements, like if the system/CPU is going to idle for X secs(residency), then the system can enter into LPS. And these are configurable and can be changed based on application needs.

@pizi-nordic If you have any suggestions on the way existing things implemented, I can definately work on them and incorporate them in my upcoming PR's.

@nashif nashif merged commit b69d286 into zephyrproject-rtos:master Aug 22, 2018
"clk_k32src",
"clk_m16src",
"sys_clock",
"UART_0",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UART may be disabled

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants