Zephyr ncs sleep modes

From Wiki at Neela Nurseries
Revision as of 05:42, 4 March 2022 by Ted (talk | contribs)
Jump to: navigation, search

Zephyr and Nordic ncs Sleep Modes 2022-01-15 Tuesday



72876 81744 59007 69773 66112 52450 psm idle current
- - - - - de A W guide

Nordic nRF9160 pin out:

Some posts and links to follow:


Looking now more closely at nRF9160 System in Package (SiP):

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.


^ 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.