This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

UART and RTT transports for logging and CLI

Hello,

I am trying to get CLI working over UART and simultaneously use RTT for logging. I don't quite get my head around this. My platform is the nRF52840 DK. I am using Segger as IDE.

I started with the CLI example making sure that that only UART transport is defined for CLI (NRF_CLI_RTT_ENABLED 0 and NRF_CLI_UART_ENABLED 1). Prints to CLI are via nrf_cli_fprintf().

For configuring logging, I am using NRF_LOG_ENABLED 1, NRF_LOG_BACKEND_RTT_ENABLED and NRF_LOG_BACKEND_FLASH_ENABLED 0 (not needing/wanting Flash log at this point). Logging is done with the NRF_LOG_INFO() macro.

In my understanding, RTT is using SWD as physical transport which the DK's MCU makes somehow accessible over the USB. UART should be mapped to the VCOM. Both transports should be independent of each other.

Now I would expect that logs appear only in the 'Debug Terminal' console (or the RTT J-Link panel, channel 0, integrated in Segger) and that I can use the CLI over VCOM. However, while CLI is only accessible over the UART, all logs are sent to the debug terminal *and* the UART (I checked with a logic analyser). Is there any reason for this? What am I missing here?

Thanks!

Parents
  • But what is not working as you expect?

    CLI apart from being command line interface it also resposible for printing logs. This was an intention when Nordic implemented new CLI.

    What is more you can configure via CLI what logs are you interested in. Basically you can filter them in runtime. For that purpose you can use commands: `log status` to check what Log are active, and you can use `log enable` or `log disable` commands to deactivate logs you don't need at the moment. By using 'log enable' command you can also configure what level of log you are interested in. For instance only logs on error level.

  • Hi Jakub,

    Thanks for the response. So probably nothing is wrong at all.

    I did not know about Nordic's intention when implementing the CLI. I thought log and CLI were two completely separate modules and could hence be routed to separate interfaces.

    I thought about using the CLI as ASCII-based M2M interface and have human-readable logs on another I/F. As the M2M should not be cluttered with logs, it seems I have to do the M2M I/F implementation the old way - no convenient shortcut here (pity).

    Thanks.

  • Hi Jakub,

    That is interesting. How do you disabled logs on the CLI to get pure CLI?

    The reason for not wanting to have logs together with the CLI is twofold:

    1. The poor controller on the other end of the link is small and slow and will have trouble doing its normal work when being bombarded with logs. All log strings need to be parsed first to be identified as irrelevant.

    2. Unfortunately, the protocol used does not allow for any 'comment' strings, i.e.everything received is interpreted as command and acted upon.

    Thanks and best regards.

  • Hi,

    Logs deactivation is pretty easy, you need to set to 0 parameter: NRF_CLI_LOG_BACKEND in sdk_config.h file.

    However shortly you will face another problem that CLI is able to receive hand typed commands but not commands send by external device. It is weakness of our UART driver which is not fast enought. For such case we have prepared dedicated library called lib_uarte.

    We have prepared an example for people who want to use CLI with external device / script (your scenario). It is proven in the battle:

    nrf5\examples\peripheral\experimental_cli_libuarte

  • Hi,

    Thanks for pointing that out. I will give it a try.

    Since my other controller is also slow, I am running the I/F at sleepy 19200bps. Maybe even that is enough for the legacy driver...? But then I know other products with nRF and 3rd party application (I won't name anyone here) which seem to have UART problems even at that speed. So probably not.

    Cheers

  • I think you will still observe the problem. Baudrate is not a problem, problem is time between send bytes. The only solution would be to add a delay between send bytes what makes limited sense ;)

    Otherwise you need to use proposed library.

  • Confirmed, NRF_CLI_LOG_BACKEND = 0 works. Great!

    For my small controller, low baudrate helps as it stretches time between RX interrupts. But anyway...

    Thanks for your help! I really appreciate the rapidity, quality and professionalism of the responses.

Reply Children
  • One more comment (also for the benefit of others): A typical M2M I/F consists of commands, responses and unsolicited events. The latter is giving trouble since there seems to be no way to print to CLI outside a command context. nrf_cli_fprintf hangs after sending a few characters - as documented in the SDK.

    So I might have to go back to allowing logs on CLI to send events and simply making sure I do not use logs anywhere else in the code.

  • Reason for not using nrf_cli_fprintf outside of command context is to prevent mixing log print and command print. You shall not observe any "hanging". Basically when log is not active nrf_cli_fprintf can be used without any limitations outside of command context.

    Outside command context you shall be able to use this function like that:

    nrf_cli_fprintf(&m_cli_uart, NRF_CLI_NORMAL, "test string\r\n");

    In addition you can use command **cli echo off** to not send back characters received by CLI. You can also compile such behavior by setting parameter NRF_CLI_ECHO_STATUS to 0 in sdk_config.h file.

  • Hmmmm, that's interesting. I just tried this once more and still observe 'hanging'. In fact, the code gets stuck in nrf_cli.c -> cli_write() waiting for tx_rdy to become 1 after having sent about 23 characters:

    while (p_cli->p_ctx->internal.flag.tx_rdy == 0)

    I thought this had something to do with the preceding comment about using transport_buffer_flush(p_cli).

  • Actually you might be right.

    Please add following code:

        transport_buffer_flush(p_cli);

    at the end of function nrf_cli_fprintf

  • Other solutions are:

    1. Set NRF_CLI_PRINTF_BUFF_SIZE to 1 in sdk_config.

    or

    2. in file nrf_cli.h change below code

    NRF_FPRINTF_DEF(CONCAT_2(name, _fprintf_ctx),                           \
                            &name,                                                  \
                            CONCAT_2(name, _ctx).printf_buff,                       \
                            NRF_CLI_PRINTF_BUFF_SIZE,                               \
                            false,                                                  \
                            nrf_cli_print_stream);                                  \
                            
                        

    to 

    NRF_FPRINTF_DEF(CONCAT_2(name, _fprintf_ctx),                           \
                            &name,                                                  \
                            CONCAT_2(name, _ctx).printf_buff,                       \
                            NRF_CLI_PRINTF_BUFF_SIZE,                               \
                            true,                                                  \
                            nrf_cli_print_stream);                                  \

    By that you will change fprintf parameter autoflush from false to true.

    I think that each of these 3 proposals will fix your case

Related