This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Using CLI alongside NRF_LOG_INFO()

Hello,

I'm trying to set up an app that enables the command line interface (CLI) over UART as well as the logging.

This is the what the main looks like:

int main(void)
{
    ret_code_t err_code;

    // Initialize nRF clock driver
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK( err_code );

    // Initialize nRF power driver
    err_code = nrf_drv_power_init(NULL);
    APP_ERROR_CHECK( err_code );

    // Initialize CLI over UART
    err_code = nrf_cli_init( &m_cli_uart );
    APP_ERROR_CHECK( err_code );

    // Start CLI service
    err_code = nrf_cli_start( &m_cli_uart );
    APP_ERROR_CHECK( err_code );

    // Setup logging
    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_INFO("Example logging\n");
    NRF_LOG_INFO("One more time\n");

    NRF_LOG_FLUSH();

    while (true)
    {
        nrf_cli_process( &m_cli_uart );
    }
}

The problem I see is that the 2 lines of logging get output but the app hangs after and I cannot interact with the CLI anymore:

>ˇ:INFO:Example logging
:INFO:One more time

Any ideas about how to get the logging working with the CLI?

  • Hi,

    The cleanest solution would be to run one of the modules on UART and the other on RTT. This way you separate the information into two channels.

    When that is said, it is possible to use the two modules together, but it will require some modifications to get it to work. The reason why it does not work "out-of-the-box" is that both modules use the UART interface, which the nRF52832 only have one of. While NRF_LOG use the UART driver directly, the CLI module use app_uart, which is an abstraction layer on top of the UART driver.

    This is what I did to get it working (note that this will affect app_uart, making it unusable in other projects and you should try this out in a separate SDK copy than your other projects):

    Move this line from app_uart_fifo.c to app_uart.h:

    static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE); 
    

    In nrf_log_backend_serial.c, add the line #include "app_uart.h" and change this line:

    static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(NRF_LOG_BACKEND_UART_INSTANCE);
    

    into:

    static nrf_drv_uart_t *m_uart = &app_uart_inst;
    

    Comment out/remove these lines:

    nrf_drv_uart_uninit(m_uart);
    ret_code = nrf_drv_uart_init(m_uart, &uart_config, blocking ? NULL : uart_event_handler);
    

    And change all occurrences of &m_uart into m_uart.

    Note that you have to call nrf_cli_init() before NRF_LOG_INIT() for this to work. Also note that if you have NRF_LOG_DEFERRED set, you need to move NRF_LOG_FLUSH() into the while loop to make it print logs.

    DISCLAIMER: This solution have not been tested beyond the point of checking that logging and CLI works simultaneously. Use at your own risk.

    Best regards,

    Jørgen

  • Thanks Jørgen! That worked great.

    Do you foresee any problems with the solution you provided? Could there be any performance hits related to power/sleep?

  • The libraries should check if the driver is busy and wait for it to become available. I have not checked the implementations in detail, but in general it should be fine to share the same interface between modules. As this method only remove the double-initialization of the UART interface, it should not affect power/sleep compared to using the modules by themselves. Note that if you disable the CLI interface, you will have to disable the LOG module first, if not the log module will not have an initialized UART interface to use.

  • Hi

    In comming SDK14 we added CLI as one of logger backends. This shall simplify CLI and Logger usage.

  • Great! Thanks Jakub for letting me know. That would be great to have.

Related