Possible to fully turn off UART from Zephyr based application?

Hello Devzone Community,

My name is Ted, and I am some way along development of Zephyr based firmware, running on an nRF9160 based custom board.  I'm looking to put the board, including LTE modem and application processor of the 9160 SiP into its lowest, deepest sleep modes.  I have found some posts somewhat related to this question -- 59007 "put-m33-mcu-in-nrf9160-sleep-mode", 66112 "best-possible-strategy-for-deep-sleep-and-awakening", 52450 "nrf9160-low-power-modes---entering-and-measuring-current" and a few additional posts -- but none of them answers key questions I am facing and not finding answers to among Devzone and other Nordic and third party documentations.

There are also some stale links in some of the above posts as they are sometimes two and three years old as of 2022 March.

My Zephyr based application is at this point multi-threaded, and I began by building on a combination of ncs v1.6,1 (Zephyr v2.6.0) sample apps "blinky", "hello_world" and "aws_iot".  In hindsight I now understand that there were multiple threads running before I created additional ones.  These include Zephyr's implementing the main() function in a thread, and the idle thread.  A census of threads is important, and so too that my application has so far used Zephyr's preferred console UART, uart0 and a second UART, uart2 for a separate custom command line interface.  From the above posts I understand that to reach the very lowest power consumption, where the 9160 application processor is fully powered down, I need to set in prj.conf the symbol CONFIG_SERIAL=n.  One post mentions that `mcuboot` and `spm` firmware modules must also be assured to have their prj.conf files disable serial port use and logging.  But I am having trouble locating the prj.conf file for Nordic's ncs/nrf/modules/mcuboot application.  There's no instance of CONFIG_SERIAL in this sub-project or application element of the larger SDK.  Am I correct here that there is not logging and not serial port use in mcuboot?

The other question I have stems from the multiple times I find mention to be sure and disable serial ports in Zephyr apps by setting CONFIG_SERIAL=n.  This is a compile time option.  I find that other parts of current firmware app stop working with this sole change CONFIG_SERIAL=y to CONFIG_SERIAL=n.  This does not make sense to me.  Does this setting turn off a portion of high speed clocks of the ARM Cortex-M33 which are also needed by on chip I2C peripherals?  When configuring no serial in prj.conf, my firmware gives no sign of life and Nordic's Power Profiler II continues to show about 700uA current draw, in spite of code that turns off the LTE modem via at_cmd_write().

In a post I made to CircuitDojo at community.jaredwolff.com the lead engineer there shared a code excerpt which he explained can, assuming driver support, dynamically turn off and on UART devices on a Zephyr supported processor.  This method is also mentioned in Devzone post 81744 from around 2021 December.  Last question I have, not answered by these more recent posts, can a run time UART setting to state PM_DEVICE_STATE_SUSPENDED permit the nRF9160 to draw its ultimately lowest spec'd current of about 1.4uA?

Fair amount of detail here, and I try to keep it short.  Thanks ahead of time for any insight Nordic Team and community can offer to my request for help!

- Ted

  • Hi,

    Just to be sure, what NCS version are you currently using?

    One post mentions that `mcuboot` and `spm` firmware modules must also be assured to have their prj.conf files disable serial port use and logging.  But I am having trouble locating the prj.conf file for Nordic's ncs/nrf/modules/mcuboot application.  There's no instance of CONFIG_SERIAL in this sub-project or application element of the larger SDK.  Am I correct here that there is not logging and not serial port use in mcuboot?

    MCUBoot does have logging enabled by default.

    The easiest way to configure child images, rather than chasing down their prj.conf files, is to add a folder called "child_image" in your project folder, and inside there a file called <child_image>.conf. I.e. for MCUBoot, you would have <your project folder>/child_image/mcuboot.conf.

    I find that other parts of current firmware app stop working with this sole change CONFIG_SERIAL=y to CONFIG_SERIAL=n.  This does not make sense to me.

    This sounds strange to me as well. What parts of the application stops working?

    Do you have any way of getting information from the device other than serial that can give us some insight into what is happening?

    What if you log over RTT instead of UART? Does your application work then?

    Last question I have, not answered by these more recent posts, can a run time UART setting to state PM_DEVICE_STATE_SUSPENDED permit the nRF9160 to draw its ultimately lowest spec'd current of about 1.4uA?

    Yes, that should disable the UART, so that the UART does not consume any power.

    You might also be interrested in the low_power_uart driver, which adds two extra GPIO pins (replacing the normal HW flow control pins), which are used to control when the UART has RX enabled (which is what requires power).

    Finally, just to be sure, could you try to meassure the current consumption with the application found in this blog post? That way we can verify that the problem is the application, and not something else in your meassurement setup.

    Best regards,

    Didrik

  • Hello Didrik,

    To your questions:

    (1)  I am using ncs v1.6.1

    (2)  In app space periodic accelerometer readings stop working.  This sensor is I2C based, and so depends on the high speed clock for operation with the app firmware.

    (3)  There is a thread I can use to flash an LED on the board, it is a custom and optional thread I'm using for new feature development.  That should only depend upon gpio type devices, not high speed clocks.

    (4)  Regarding RTT logging, this is less accessible to me as I am building and developing at the command line on Linux, and have Segger installed in only one of the places I get to work.  But I'm noting this UART based alternative for debugging.  Thank you for educating me!

    I am working presently to implement a couple of tests and confirm or disconfirm the seeming "dead in the water" nature of my app when CONFIG_SERIAL=n in the app's prj.conf file.  I'll update you on my findings in this regard, soon as possible.

    Thank you also for explaining the use of `child_image` directory and amending files added there, per your example `child_image/mcuboot.conf`.  These conf files sound akin to the manner in which device tree language supports additive and change-wise amendments in dot overlay files.  That will be helpful to keep such configuration changes in application space, where they can be git tracked.

    By the way I think that a hyperlink to the blog post you mention at end of your message might be missing.  I don't know which blog to which you refer, and cannot review that.

    To confirm then, I may keep CONFIG_SERIAL=y, and on demand suspend one or more on-chip UARTs by calling pm_device_state_set(zephyr_device_handle, <new state>, NULL, NULL), and enjoy the lowest nRF9160 power consumption as if I had disabled all UARTs at compile time?

    - Ted

  • tedhavelka said:
    By the way I think that a hyperlink to the blog post you mention at end of your message might be missing.  I don't know which blog to which you refer, and cannot review that.

    Yes, sorry. Here is the link: https://devzone.nordicsemi.com/guides/cellular-iot-guides/b/hardware-design/posts/getting-started-with-current-measurements-on-the-nrf9160?CommentId=b6127988-c126-4d90-a566-86596e84a0f0

    I've also edited my previous reply to include the link.

    tedhavelka said:
    To confirm then, I may keep CONFIG_SERIAL=y, and on demand suspend one or more on-chip UARTs by calling pm_device_state_set(zephyr_device_handle, <new state>, NULL, NULL), and enjoy the lowest nRF9160 power consumption as if I had disabled all UARTs at compile time?

    Yes. That should disable UART RX, which is what uses the HF clock and consumes power.

    tedhavelka said:
    (4)  Regarding RTT logging, this is less accessible to me as I am building and developing at the command line on Linux, and have Segger installed in only one of the places I get to work.  But I'm noting this UART based alternative for debugging.  Thank you for educating me

    You don't need the full Segger Embedded Studio IDE to read RTT.

    J-Link RTT Viewer works on Linux, or you can use the command line: https://infocenter.nordicsemi.com/topic/ug_gsg_ses/UG/gsg/connect_rtt_linux.html

  • Hello Didrik,

    Thank you for the link to command line JLinkExe utility.  It turns out I have that installed, it's alongside `nrfjprog` which I use at the command line.  I just had not occasion yet to review all the utilities which install with Segger JLink drivers for Linux.

    I'm searching for examples now but you may be able to speed me there sooner:  is the API macro or function I need to send messages to RTT console `NRF_LOG()`?  This question I make in the context of Nordic ncs 1.6.1 and a Zephyr based application.

    - Ted

  • tedhavelka said:
    I'm searching for examples now but you may be able to speed me there sooner:  is the API macro or function I need to send messages to RTT console `NRF_LOG()`?  This question I make in the context of Nordic ncs 1.6.1 and a Zephyr based application.

    NRF_LOG was used in the nRF5 SDK.

    In NCS, the corresponding macro is LOG_<level>, where <level> is one of DBG, INF, WRN, ERR.

    printf() or printk() can also be used.

    However, to get the output over RTT, you must enable the RTT backend:

    # Enable RTT
    CONFIG_USE_SEGGER_RTT=y
    
    # Send log over RTT
    CONFIG_LOG_BACKEND_RTT=y
    #(Optionally also CONFIG_LOG_BACKEND_UART=n, you'll probably get some Kconfig warnings without)
    
    # Send printk/printf over RTT
    CONFIG_RTT_CONSOLE=y
    #(Optionally also CONFIG_UART_CONSOLE=n)

Related