example code:
~/ncs/zephyr/samples/boards/nrf/system_off
build type - nrf9160ns
prj.conf:
CONFIG_PM=y
CONFIG_PM_DEEP_SLEEP_STATES=y
# Required to disable default behavior of deep sleep on timeout
CONFIG_PM_STATE_LOCK=y
CONFIG_PM_DEVICE=y
CONFIG_GPIO=y
CONFIG_DEBUG=y
CONFIG_FAULT_DUMP=1
CONFIG_UART_CONSOLE=n
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN=2048
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=2048
# flash write
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_FLASH_PAGE_LAYOUT=y
# enable mcuboot/boot/zephyr project
CONFIG_BOOTLOADER_MCUBOOT=y
when run to
pm_power_state_force(POWER_STATE_DEEP_SLEEP_1);
will crash
///////////////////////trace to kernel
/root/ncs/zephyr/subsys/power/device.c
static int _pm_devices(uint32_t state)
when dev is UART_0 or UART_1 will crash
rc = device_set_power_state(dev, state, NULL, NULL);
///////////////////////now fix to
static int _pm_devices(uint32_t state)
{
bool is_suspend, is_uart;
num_susp = 0;
for (int i = num_pm - 1; i >= 0; i--) {
device_idx_t idx = pm_devices[i];
const struct device *dev = &all_devices[idx];
int rc;
/* TODO: Improve the logic by checking device status
* and set the device states accordingly.
*/
is_suspend = (state == DEVICE_PM_SUSPEND_STATE || state == DEVICE_PM_FORCE_SUSPEND_STATE);
is_uart = (strstr(dev->name, "UART") != NULL);
if( !is_suspend || !is_uart )
{
rc = device_set_power_state(dev, state, NULL, NULL);
if ((rc != -ENOTSUP) && (rc != 0)) {
LOG_DBG("%s did not enter %s state: %d",
dev->name, device_pm_state_str(state), rc);
return rc;
}
}
++num_susp;
}
return 0;
}