samples: nrf: system_off: show how to disable deep sleep

Due to a long standing difference of requirements enabling deep sleep
will by default cause any application that delays for an unbounded
period to power down.  On Nordic doing so turns the system off.  Show
how to prevent this from happening while still allowing deep sleep
states to be available for the application's controlled use.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-07-01 09:46:32 -05:00 committed by Carles Cufí
commit 1688f8c740
2 changed files with 23 additions and 5 deletions

View file

@ -17,6 +17,11 @@ deep sleep on Nordic platforms. The functional behavior is:
A power monitor will be able to distinguish among these states.
This sample also demonstrates the use of a :c:func:`SYS_INIT()` call to
disable the deep sleep functionality before the kernel starts, which
prevents the board from powering down during initialization of drivers
that use unbounded delays to wait for startup.
Requirements
************

View file

@ -7,6 +7,7 @@
#include <stdio.h>
#include <zephyr.h>
#include <device.h>
#include <init.h>
#include <power/power.h>
#include <hal/nrf_gpio.h>
@ -15,6 +16,23 @@
#define BUSY_WAIT_S 2U
#define SLEEP_S 2U
/* Prevent deep sleep (system off) from being entered on long timeouts
* or `K_FOREVER` due to the default residency policy.
*
* This has to be done before anything tries to sleep, which means
* before the threading system starts up between PRE_KERNEL_2 and
* POST_KERNEL. Do it at the start of PRE_KERNEL_2.
*/
static int disable_ds_1(struct device *dev)
{
ARG_UNUSED(dev);
sys_pm_ctrl_disable_state(SYS_POWER_STATE_DEEP_SLEEP_1);
return 0;
}
SYS_INIT(disable_ds_1, PRE_KERNEL_2, 0);
void main(void)
{
int rc;
@ -28,11 +46,6 @@ void main(void)
nrf_gpio_cfg_sense_set(DT_GPIO_PIN(DT_NODELABEL(button0), gpios),
NRF_GPIO_PIN_SENSE_LOW);
/* Prevent deep sleep (system off) from being entered on long
* timeouts due to the default residency policy.
*/
sys_pm_ctrl_disable_state(SYS_POWER_STATE_DEEP_SLEEP_1);
printk("Busy-wait %u s\n", BUSY_WAIT_S);
k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC);