-
Notifications
You must be signed in to change notification settings - Fork 7k
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
OS Managed Power Management framework #9416
Conversation
Codecov Report
@@ 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.
|
#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) | ||
case SYS_POWER_STATE_DEEP_SLEEP: | ||
#endif | ||
lps_flag = true; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
subsys/power/policy.c
Outdated
#include <soc.h> | ||
#include <soc_power.h> | ||
|
||
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_PM_LEVEL |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok will fix it.
subsys/power/Kconfig
Outdated
config PM_CONTROL_OS_LPS | ||
bool "Platfrom supports LPS" | ||
help | ||
This is the maximum number of bytes that the |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
subsys/power/device.c
Outdated
* and clock domain dependencies. | ||
*/ | ||
#ifdef CONFIG_SOC_SERIES_NRF52X | ||
#define CONFIG_MAX_PM_DEVICES 15 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
subsys/power/device.c
Outdated
* 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], |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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], |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
subsys/power/device.c
Outdated
} | ||
} | ||
|
||
if (is_core_dev) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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>
4086eba
to
97ead6d
Compare
@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. |
97ead6d
to
c50a04b
Compare
@pizi-nordic @dbkinder I have addressed your comments and updated the PR, please have a look. |
@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? |
|
c50a04b
to
d31d784
Compare
subsys/power/pm_policy.h
Outdated
extern void sys_pm_create_device_list(void); | ||
|
||
/** | ||
* @brief Function to supend the devices in PM device list |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will fix it.
subsys/power/policy.c
Outdated
#else | ||
#define SECS_TO_TICKS 100 | ||
#endif | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, will fix it.
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>
d31d784
to
7f6d3e5
Compare
@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 |
@pdunaj: FYI |
@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 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
@pizi-nordic _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. |
"clk_k32src", | ||
"clk_m16src", | ||
"sys_clock", | ||
"UART_0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UART may be disabled
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