lib: os: add support for system power off

Add a new API to perform an immediate system power off:
`sys_poweroff()`.

Until now, this functionality has been implemented via the system power
management module, but in a clunky fashion. The way system PM works is
by defining some idle states in devicetree, that, given some properties
(e.g. minimal residency, exit latency, etc.) are automatically selected
when system goes to idle based on the expected next wake-up. However,
system off is a power state that one typically wants to control manually
from the application because it implies state loss, and in most cases,
configuring some sort of wake-up source. So in general, it is not
desired to let the system enter this state automatically. This led to
the following stuff in-tree:

from `boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts`:

```c
/*
 * Deep power-down mode is supported in this SoC through
 *  'PM_STATE_SOFT_OFF' state. There is no entry for this in device tree,
 *  user can call pm_state_force to enter this state.
 */
```

That is, state not being defined in devicetree so that PM subsystem
doesn't pick it automatically, but still implemented in in the PM hooks:

from `soc/arm/nxp_imx/rt5xx/power.c`, `pm_state_set()`:
```c
case PM_STATE_SOFT_OFF:
	set_deepsleep_pin_config();
	POWER_EnterDeepPowerDown(EXCLUDE_FROM_DEEP_POWERDOWN);
	break;
```

And to actually make use of this state, users had to do this kind of
abominations:

```c
pm_state_force(0u, &(struct pm_state_info){ PM_STATE_SOFT_OFF, 0, 0 });

/* Now we need to go sleep. This will let the idle thread runs and
 * the pm subsystem will use the forced state. To confirm that the
 * forced state is used, lets set the same timeout used previously.
 */
k_sleep(K_SECONDS(SLEEP_S));

printk("ERROR: System off failed\n");
while (true) {
	/* spin to avoid fall-off behavior */
}
```

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
This commit is contained in:
Gerard Marull-Paretas 2023-07-20 11:46:41 +02:00 committed by Carles Cufí
parent cbfa472fa7
commit 90b247b90b
6 changed files with 88 additions and 0 deletions

View file

@ -22,6 +22,7 @@ OS Services
notify.rst
pm/index.rst
portability/index.rst
poweroff.rst
shell/index.rst
settings/index.rst
smf/index.rst

View file

@ -0,0 +1,6 @@
.. _poweroff:
Power off
#########
.. doxygengroup:: sys_poweroff

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_SYS_POWEROFF_H_
#define ZEPHYR_INCLUDE_SYS_POWEROFF_H_
#include <zephyr/toolchain.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup sys_poweroff System power off
* @ingroup os_services
* @{
*/
/** @cond INTERNAL_HIDDEN */
/**
* @brief System power off hook.
*
* This function needs to be implemented in platform code. It must only
* perform an immediate power off of the system.
*/
FUNC_NORETURN void z_sys_poweroff(void);
/** @} */
/** @endcond */
/**
* @brief Perform a system power off.
*
* This function will perform an immediate power off of the system. It is the
* responsability of the caller to ensure that the system is in a safe state to
* be powered off. Any required wake up sources must be enabled before calling
* this function.
*
* @kconfig{CONFIG_POWEROFF} needs to be enabled to use this API.
*/
FUNC_NORETURN void sys_poweroff(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_SYS_POWEROFF_H_ */

View file

@ -68,6 +68,8 @@ zephyr_sources_ifdef(CONFIG_SYS_MEM_BLOCKS mem_blocks.c)
zephyr_sources_ifdef(CONFIG_WINSTREAM winstream.c)
zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c)
zephyr_library_include_directories(
${ZEPHYR_BASE}/kernel/include
${ZEPHYR_BASE}/arch/${ARCH}/include

View file

@ -166,6 +166,17 @@ config REBOOT
needed to perform a "safe" reboot (e.g. to stop the system clock before
issuing a reset).
config HAS_POWEROFF
bool
help
Option to signal that power off functionality is implemented.
config POWEROFF
bool "Power off functionality"
depends on HAS_POWEROFF
help
Enable support for system power off.
config UTF8
bool "UTF-8 string operation supported"
help

14
lib/os/poweroff.c Normal file
View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/irq.h>
#include <zephyr/sys/poweroff.h>
void sys_poweroff(void)
{
(void)irq_lock();
z_sys_poweroff();
}