Zephyr ncs sleep modes
Zephyr and Nordic ncs Sleep Modes 2022-01-15 Tuesday
Keywords: nRF9160 low power
Contents
72876 | 81744 | 59007 | 69773 | 66112 | 52450 | psm idle current |
- | - | enter_sleep | - | - | de A W | guide |
0311
- https://devzone.nordicsemi.com/f/nordic-q-a/69557/periodic-current-spikes-on-sleep periodic-current-spikes-on-sleep
Nordic nRF9160 pin out:
Some posts and links to follow:
-
And from this post, note however these forum replies are for Nordic nRF5x family parts:
- https://devzone.nordicsemi.com/f/nordic-q-a/51648/how-to-put-nrf52840-to-deep-sleep-system-off/207410#207410 post ~two years ago (2019) by Nordic Semi Amanda Hsieh
- https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html&cp=4_2_0_17_1&anchor=unique_2047546596
Looking now more closely at nRF9160 System in Package (SiP):
- https://infocenter.nordicsemi.com/topic/nwp_041/WP/nwp_041/sleep_types/flight_mode_sleep.html
- https://infocenter.nordicsemi.com/topic/nwp_041/WP/nwp_041/example_sequences/uplink_data_psm.html
- https://infocenter.nordicsemi.com/topic/ps_nrf9160/product_overview.html
- https://infocenter.nordicsemi.com/topic/ps_nrf9160/chapters/current_consumption/doc/frontpage.html
Oh and a note on nRF9160 watchdog timer:
This looks important:
^ 2022-02-17 Thursday
Continuing the search at https://nordicsemi.com with pattern "nRF9160 application processor", first a news press then the downloads page for this SiP:
An excerpt from the above article mentions some power management details of the nRF9160 SiP not seen elsewhere so far: " A light and compact asset tracker ShipSafe takes advantage of the nRF9160’s compact dimensions (10 x 16 x 1 mm) to incorporate the SiP, a Wi-Fi chipset, sensors, LED, peripheral components, battery and Wi-Fi and Cellular antennas into a device measuring just 120 x 75 x 16 mm and weighing 145 gm. The nRF9160 SiP’s 64 MHz Arm® Cortex®-M33 processor provides sufficient computational power to not only run the LTE-M cellular connectivity but also all other product functionality. The 1 MB Flash and 256 KB RAM supports fast response and complex application software.
The nRF9160 SiP is certified for global cellular IoT applications, comprising a dedicated application processor and memory, multimode LTE-M/NB-IoT modem with integrated RF front end (RFFE), GPS, and power management in a compact package. The SiP incorporates the Arm M33 processor, Flash and RAM, a range of analog and digital peripherals, automated power and clock management, Arm TrustZone® for trusted execution, and Arm CryptoCell™ 310 for application layer security. The processor communicates with the LTE modem through a BSD secure sockets API and supports the application layer protocol (for example CoAP, MQTT or LWM2M) and the application itself. The nRF9160 SiP’s LTE modem supports both SIM and eSIM, offers 700 to 2200 MHz LTE band support, 23 dBm output power, and single pin 50 Ω antenna- and UICC-interfaces. The LTE stack layers L1-L3, IPv4/IPv6, TCP/UDP, TLS/DTLS are part of the modem firmware. "
nRF91 Series >> nRF9160 >> Guidelines
^ nRF9160 Sleep and Low Power Mode Forum Posts
nRF9160 sleep mode not working in SDK 'nrf' v1.6.1, works in 1.7.0 . . .
Symbol 'PSM' may be a more apt symbol for which to search, also looks like power savings modes may only be practical with certain network providers:
2022-02-16 WED - Inquiring at CircuitDojo about where to find low power, sleep and deep sleep mode settings, APIs for these in nRF9160 based designs:
In first reply a recommendation to review `nfed` sample application named 'active_sleep':
2022-02-18 FRI - A post by developer Norbert asking about how to effectively disable UARTE for lower power operation . . .
^ nRF9160 Power Saving Mode(s) Examples
Power Savings Mode Ten Minutes Period Example
Excerpts from this post:
-
"In order to achieve the lowest possible current consumption, logging has to be turned off. This is done by,
Adding the CONFIG_SERIAL=n flag to the prj.conf file in the project folder.
Adding the CONFIG_SERIAL=n to the SPM prj.conf file. This is located in the SDK_ROOT/nrf/samples/nrf9160/spm folder."
An example from Jared Wolff of CircuitDojo, see line 135 in main.c:
Zephyr Project documentation regarding `k_cpu_idle()`:
^ Zephyr Power Management
2022-02-21 Monday - Looking into Zephyr Power Management (PM) based on recent response and help from Jared Wolff. The following Zephyr documentation page goes into great detail about Zephyr's power management facilities, and has multiple links to related Zephyr documentation:
Jared Wolff's response to forum post **blah** gives a code example which calls two Zephyr API routines to turn off a UART at run time. One of these routines is `uart_rx_disable()`, which in Zephyr source tree appears in following places:
ted@localhost:~/projects/zephyr-based/zephyr$ grep -nr uart_rx_disable ./* ./drivers/serial/uart_handlers.c:94:#include <syscalls/uart_rx_disable_mrsh.c> ./include/drivers/uart.h:76: * Receiving can be disabled using uart_rx_disable, after calling that ./include/drivers/uart.h:111: * - After uart_rx_disable(). ./include/drivers/uart.h:619:__syscall int uart_rx_disable(const struct device *dev); ./include/drivers/uart.h:621:static inline int z_impl_uart_rx_disable(const struct device *dev) ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:235: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:302: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:315: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:378: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:447: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:516: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_async_api/src/test_uart_async.c:600: uart_rx_disable(uart_dev); ./tests/drivers/uart/uart_pm/src/main.c:101: err = uart_rx_disable(dev); ted@localhost:~/projects/zephyr-based/zephyr$
The _mrsh identifies a Zephyr unmarshalling function, which is mentioned here in Zephyr documentation:
From file ./zephyr/include/generated/syscalls/uart.h:
49 50 extern int z_impl_uart_rx_enable(const struct device * dev, uint8_t * buf, size_t len, int32_t timeout); 51 static inline int uart_rx_enable(const struct device * dev, uint8_t * buf, size_t len, int32_t timeout) 52 { 53 #ifdef CONFIG_USERSPACE 54 if (z_syscall_trap()) { 55 return (int) arch_syscall_invoke4(*(uintptr_t *)&dev, *(uintptr_t *)&buf, *(uintptr_t *)&len, *(uintptr_t *)&timeout, K_SYSCALL_UART_RX_ENABLE); 56 } 57 #endif 58 compiler_barrier(); 59 return z_impl_uart_rx_enable(dev, buf, len, timeout); 60 } 61 62 63 extern int z_impl_uart_rx_disable(const struct device * dev); 64 static inline int uart_rx_disable(const struct device * dev) 65 { 66 #ifdef CONFIG_USERSPACE 67 if (z_syscall_trap()) { 68 return (int) arch_syscall_invoke1(*(uintptr_t *)&dev, K_SYSCALL_UART_RX_DISABLE); 69 } 70 #endif 71 compiler_barrier(); 72 return z_impl_uart_rx_disable(dev); 73 } 74
2022-03-02 - Simiarly in the project build directory itself we find [west_workspace]/[project]/build/zephyr/include/generated/syscalls/uart.h:
62 63 extern int z_impl_uart_rx_disable(const struct device * dev); 64 static inline int uart_rx_disable(const struct device * dev) 65 { 66 #ifdef CONFIG_USERSPACE 67 if (z_syscall_trap()) { 68 return (int) arch_syscall_invoke1(*(uintptr_t *)&dev, K_SYSCALL_UART_RX_DISABLE); 69 } 70 #endif 71 compiler_barrier(); 72 return z_impl_uart_rx_disable(dev); 73 } 74 75
Kconfig symbol here is CONFIG_USERSPACE, project menuconfig shows symbol USERSPACE(=n) "User mode threads"
.
And in file `[west_workspace]/zephyr/include/drivers/uart.h`:
604 /** 605 * @brief Disable RX 606 * 607 * @ref uart_event_type::UART_RX_BUF_RELEASED event will be generated for every 608 * buffer scheduled, after that @ref uart_event_type::UART_RX_DISABLED event 609 * will be generated. Additionally, if there is any pending received data, the 610 * @ref uart_event_type::UART_RX_RDY event for that data will be generated 611 * before the @ref uart_event_type::UART_RX_BUF_RELEASED events. 612 * 613 * @param dev UART device structure. 614 * 615 * @retval -ENOTSUP If not supported. 616 * @retval -EFAULT There is no active reception. 617 * @retval 0 If successful, negative errno code otherwise. 618 */ 619 __syscall int uart_rx_disable(const struct device *dev); 620 621 static inline int z_impl_uart_rx_disable(const struct device *dev) 622 { 623 #ifdef CONFIG_UART_ASYNC_API 624 const struct uart_driver_api *api = 625 (const struct uart_driver_api *)dev->api; 626 627 return api->rx_disable(dev); 628 #else 629 return -ENOTSUP; 630 #endif 631 } 632
Kconfig symbol here is UART_ASYNC_API(=n) "Enable new asynchronous UART API [EXPERIMENTAL]"
.
2022-02-24 Thursday
CPU idle mode and k_cpu_idle(), k_cpu_atomic_idle() . . .
Devzone post 71977 a good explanation of k_sleep() and reasons to use Zephyr kernel sleep functions over hand-rolled implementations:
^ connection_poll_thread
Searching for aws_iot shared sample app library references to `connection_poll_thread`, in order to remove a now redundantly instantiated and started Zephyr thread:
now at /home/ted/projects/zephyr-based/nrf ted@vibratsiya:~/projects/zephyr-based/nrf$ grep -nr connection_poll_thread ./* ./modules/memfault/memfault_ncs_metrics.c:43: } else if (strncmp("connection_poll_thread", name, ./modules/memfault/memfault_ncs_metrics.c:44: sizeof("connection_poll_thread")) == 0) { ./modules/memfault/memfault_ncs_metrics.c:66: LOG_DBG("Unused connection_poll_thread stack size: %d", unused); ./modules/memfault/Kconfig:119: - connection_poll_thread, used by the cloud libraries for ./subsys/net/lib/nrf_cloud/src/nrf_cloud.c:447:K_THREAD_DEFINE(connection_poll_thread, POLL_THREAD_STACK_SIZE, ./subsys/net/lib/azure_iot_hub/src/azure_iot_hub.c:1454:K_THREAD_DEFINE(connection_poll_thread, CONFIG_AZURE_IOT_HUB_STACK_SIZE, ./subsys/net/lib/aws_iot/src/aws_iot.c:1335:K_THREAD_DEFINE(connection_poll_thread, POLL_THREAD_STACK_SIZE, ted@vibratsiya:~/projects/zephyr-based/nrf$ vi modules/memfault/Kconfig
Among these text search results we're not seeing where there is a thread given the name `connection_poll_thread`, and yet this name appears among Zephyr kernel's reporting of running threads.
Ok here is where `connection_poll_thread` is being instantiated in `[ncs_workspace]/nrf/subsys/net/lib/aws_iot/aws_oit.c beginning on line 1335. The difficulty to disable this is that it is bounded by the pound defined symbol `CONFIG_AWS_IOT_CONNECTION_POLL_THREAD`. We can eventually define this symbol as `n` for no, but this will likely require some further project factoring work. In other words we have not completely removed out dependency from Nordic aws_iot or related sample app libraries.
Figure x - code excerpt where aws_iot.c instantiates connection_poll_thread
1329 1330 #ifdef CONFIG_BOARD_QEMU_X86 1331 #define POLL_THREAD_STACK_SIZE 4096 1332 #else 1333 #define POLL_THREAD_STACK_SIZE 3072 1334 #endif 1335 K_THREAD_DEFINE(connection_poll_thread, POLL_THREAD_STACK_SIZE, 1336 aws_iot_cloud_poll, NULL, NULL, NULL, 1337 K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0); 1338 #endif /* defined(CONFIG_AWS_IOT_CONNECTION_POLL_THREAD) */
Better news, it appears `CONFIG_AWS_IOT_CONNECTION_POLL_THREAD` is referenced only two times in aws_iot.c, and not any other aws_iot sample app or related sample app source or library files. We may be able to readily create a Kconfig specific to our project and in this declare a tantamount symbol by a distinct name. This would be the cleanest way to continue the library code porting and modifying effort. '
We were able to successfully remove the Zephyr macro based code which instantiated and apparently allowed to start the original aws_iot connection poll thread. We created a like Kconfig symbol in our project's top level Kconfig file, modeled after AWS_IOT_CONNECTION_POLL_THREAD which is defined in Nordic's AWS sample apps library file `nrf/subsys/net/lib/aws_iot/Kconfig`. We must create the symbol, and then reference it by a second symbol in top level prj.conf, that second symbol following the name of the first symbol but with CONFIG_ prepended to it.
^ Zephyr RTOS and PSM settings
As often we begin with Devzone posts from Nordic. This first post identifies some details regarding AT+CPSMS command and a distinction between `Periodic-TAU` and `Periodic-TAU-ext`:
Unsure how useful this will be but page holds summary of ARM Cortex-M features, handful of ARM versions up to including Cortex-M23:
^ Terms
There are a lot of terms and acronyms associated with LTE modem and Nordic Semi SoC and SiP parts. Here we capture a few of those in our quest for low power modes understanding.
- UICC . . . Universal Integrated Circuit Card. See Modem Sleep Notifications terms page.
- eDRX . . . Extended Discontinuous Reception
- RTT . . . Real Time Transfer. A Segger + JLink specific protocol, see https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v11.0.0%2Flib_nrf_log.html
-
Found mention of eDRX while searching Nordic Devzone forum for 'UICC':
https://devzone.nordicsemi.com/f/nordic-q-a/76896/rerouting-at-interface-for-power-measurement-using-external-supply/318244#318244
^ Pattern Searches in Zephyr and NRF Repositories
Some searches whose results to further explore . . .
ted@localhost:~/projects/zephyr-based/zephyr$ grep -nr sleeping ./* ./arch/arm/core/aarch32/cpu_idle.S:125: * Lock PRIMASK while sleeping: wfe will still get interrupted by ./arch/arm/core/aarch32/nmi_on_reset.S:12: * is to hard hang, sleeping. ./boards/posix/native_posix/doc/index.rst:56:simulated CPU is sleeping. ./doc/guides/porting/arch.rst:226:yielding/sleeping primitives.