Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

what are the required steps/files/definitions/commands to get RTT output from a custom app into RTT Viewer ?

I am using an nRF chip and the nRF SDK for 1st time and I think I am still at the steep part of the learning curve.

My problem is that I cannot get the log from my custom app in RTT Viewer. I use:

  • custom PCB with Taiyo Yuden EYSKBNZWB/nRF52840 Wireless Module
  • SDK 17.0.2
  • arm gcc 10.3.1
  • J-Link RTT Viewer V7.52b (JLinkRTTViewerExe)
  • nRF5_SDK/examples/peripheral/template_project

In my main.c source file I have included the following headers: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Flib_nrf_log.html

  • #include "nrf_log_ctrl.h"
  • #include "nrf_log_default_backends.h"
  • #include "nrf_log.h"

Again in the main.c source file, I have the define - https://devzone.nordicsemi.com/f/nordic-q-a/29977/undefined-reference-to-nrf_log_default_backend_init

  • #define NRF_LOG_BACKEND_RTT_ENABLED 1

In the Makefile @ nRF5_SDK/examples/peripheral/template_project/pca10056/blank/armgcc I added the following line:

  • $(SDK_ROOT)/components/libraries/log/src/nrf_log_default_backends.c \

in order to solve the linker issue: main.c: undefined reference to `nrf_log_default_backends_init'

In the sdk_config.h file @ nRF5_SDK/examples/peripheral/template_project/pca10056/blank/config I have the follwoing settings:

The contents of my main.s source file are:

int main ( void ) {
    ret_code_t err_code = NRF_LOG_INIT ( NULL );
    APP_ERROR_CHECK ( err_code );
    NRF_LOG_DEFAULT_BACKENDS_INIT ();
    
    while ( true ) {
        uint32_t i ;

        for ( i = 0; i < 10; i++ ) {
            NRF_LOG_INFO ( "i = %u\r\n", i );
        }
    }
}

I thought that I could see some numbers printed in RTT VIewer but unfortunately I still can't manage to get the RTT output into the RTT Viewer after reading several posts so I would ask for help at this point. Any would be highly appreciated :-)

P.S. I think the connection PC <-> J-Link <-> PCB works fine as I managed to get an LED blink ca. every second.

  • Hi, Simon,

    thanks for your reply and suggestion !

    Just built and flashed the temperature project, with a semi-successful result :-)

    The code I used is (I commented out the temperature part and left only the first log output statement with an LED switch-on after it):

    // #includes ...
    // #defines ...
    
    int main ( void ) {
        nrf_gpio_cfg_output ( LED_PIN ) ;
        
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        NRF_LOG_INFO("Temperature example started.");
        
        nrf_gpio_pin_set ( LED_PIN );
    }

    The results are as follows:

    Setting 1 (sdk_config.h):

    NRF_LOG_BACKEND_UART_ENABLED 0

    NRF_LOG_BACKEND_RTT_ENABLED 1

    NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1 or 0

    NRF_LOG_ENABLED 1

    NRF_LOG_DEFERRED 1

    No output in RTT Viewer ! --> from what I could read, this can be explained by the fact that I don't have a call to

    NRF_LOG_PROCESS() in my code, hence I don't see the output. This is understandable.

    Setting 2 (sdk_config.h):

    NRF_LOG_BACKEND_UART_ENABLED 0

    NRF_LOG_BACKEND_RTT_ENABLED 1

    NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1 or 0

    NRF_LOG_ENABLED 1

    NRF_LOG_DEFERRED 0

    Output in RTT Viewer is shown, but only the 1st time after a connection is established !

    However, no output is shown if the program is for example reset via “nrfjprog -f nrf52 –reset” with a running RTT Viewer connection !

    For the output to be shown again, the connection in RTT Viewer must be first disconnected, and then re-established AFTER the chip has been previously reset, e.g.

    1. chip reset

    2. (Connection lost) via File → Disconnect 

    3. File → Connect

      Output:

      00> <info> app: Temperature example started.

      00>

    i.e. output is shown when:

    1. chip is reset

    2. RTT Viewer is disconnected

    3. RTT Viewer is re-connected anew

     

    Modifying NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED as described in:

    Link: https://devzone.nordicsemi.com/f/nordic-q-a/46685/no-log-output-to-debug-terminal-in-ses-or-rtt-viewer

    does not change the situation !

    The only difference is the number of output lines being output in RTT Viewer, i.e.

    NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 0

    Output:

    00> <info> app: Temperature example started.

    NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1

    Output:

    00> <info> app: Temperature example started.

    00>

    => in the 2nd case two lines are printed as output, whereas in the 1st case only 1 line is printed as output !

     

    Do you know what is the reason for this behavior and what needs to be done to solve it ?
    This apart, could you elaborate on:
    actually implement the RTT backend

    What does it exactly mean to implement the RTT backend ? Could you point me to a resource where all the required steps are described in terms of required headers / sources / Makefile settings / sdk_config.h settings, or alternatively just type them here in as the logging functionality is so fundamental ?

    Greets and thanks again

    Mario

  • Hi again

    I just ran the temperature project on my end to see if I could replicate it, and I see the "Temperature example started" message every time I press the reset pin on my DK. How exactly do you reset your device on your end?

    What's necessary to enable the RTT backend on any example should be adding the following defines in sdk_config.h

    // <e> NRF_LOG_ENABLED - nrf_log - Logger
    //==========================================================
    #ifndef NRF_LOG_ENABLED
    #define NRF_LOG_ENABLED 1
    #endif
    
    // <h> nRF_Log 
    
    //==========================================================
    // <e> NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend
    //==========================================================
    #ifndef NRF_LOG_BACKEND_RTT_ENABLED
    #define NRF_LOG_BACKEND_RTT_ENABLED 1
    #endif
    // <o> NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings. 
    // <i> Size of the buffer is a trade-off between RAM usage and processing.
    // <i> if buffer is smaller then strings will often be fragmented.
    // <i> It is recommended to use size which will fit typical log and only the
    // <i> longer one will be fragmented.
    
    #ifndef NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE
    #define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64
    #endif
    
    // <o> NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS - Period before retrying writing to RTT 
    #ifndef NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS
    #define NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS 1
    #endif
    
    // <o> NRF_LOG_BACKEND_RTT_TX_RETRY_CNT - Writing to RTT retries. 
    // <i> If RTT fails to accept any new data after retries
    // <i> module assumes that host is not active and on next
    // <i> request it will perform only one write attempt.
    // <i> On successful writing, module assumes that host is active
    // <i> and scheme with retry is applied again.
    
    #ifndef NRF_LOG_BACKEND_RTT_TX_RETRY_CNT
    #define NRF_LOG_BACKEND_RTT_TX_RETRY_CNT 3
    #endif
    
    // </e>
    
    // <h> nRF_Segger_RTT 
    
    //==========================================================
    // <h> segger_rtt - SEGGER RTT
    
    //==========================================================
    // <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. 
    // <i> Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE
    // <i> or this value is actually used. It depends on which one is bigger.
    
    #ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
    #define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 512
    #endif
    
    // <o> SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Maximum number of upstream buffers. 
    #ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
    #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
    #endif
    
    // <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of downstream buffer. 
    #ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
    #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
    #endif
    
    // <o> SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Maximum number of downstream buffers. 
    #ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
    #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
    #endif
    
    // <o> SEGGER_RTT_CONFIG_DEFAULT_MODE  - RTT behavior if the buffer is full.
     
    
    // <i> The following modes are supported:
    // <i> - SKIP  - Do not block, output nothing.
    // <i> - TRIM  - Do not block, output as much as fits.
    // <i> - BLOCK - Wait until there is space in the buffer.
    // <0=> SKIP 
    // <1=> TRIM 
    // <2=> BLOCK_IF_FIFO_FULL 
    
    #ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
    #define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
    #endif

    You'll also have to add the nrf_log_backend_rtt.h/.c and SEGGER_RTT.h/ .c files to the project.

    Best regards,

    Simon

  • Hi, Simon,

    thank you for your reply ! It was exactly what I wanted to know and it answers perfectly my original question :-)

    You'll also have to add the nrf_log_backend_rtt.h/.c and SEGGER_RTT.h/ .c files to the project.

    I think what I was missing and not knowing about was the SEGGER part, because I didn't encounter them when I read about the Logger module in the infocenter, and also because I hadn't seen SEGGER files in the Makefile of the template_project, which I originally started with and used for testing. Many thanks for mentioning them and copying the corresponding required #defines in the sdk_config.h file !

    In the meantime I read through the SAADC example too, and I think it helped me get the big picture to a decent extent regarding the use / inclusion of modules :-)

    That apart, I couldn't solve my issue with the lack of output after reset :-(

    How exactly do you reset your device on your end?

    I used the reset command I found in the Makefile under the "flash" recipe, i.e I ran in a Terminal:

    nrfjprog -f nrf52 --reset

    Could this influence the RTT logging ?

    Thanks once again

    Mario

  • Okay, glad to hear we've resolved one part of the problem then!

    Okay, seeing as you're using nrfjprog to do the reset that makes sense. nrfjprog halts the CPU to hijack the debug/trace module and thus disconnect the RTT viewer from the J-Link device. Unfortunately, the RTT viewer does not have the feature that some serial terminals do (like teraterm for instance) where it is able to detect when the COM port is available again and automatically reconnect.

    You will either need to do logging over UART (serial) with a terminal that has this feature, or reset the device in your application, either by a button reset or a timeout that resets the device to be able to see the logging behave correctly. It seems like your application runs as intended, but that the RTT viewer is disconnected when you do the nrfjprog reset and thus you don't see any further logging information.

    Best regards,

    Simon

  • the RTT viewer is disconnected when you do the nrfjprog reset and thus you don't see any further logging information

    Yes, this is unfortunately true. However, Segger's J-Link Commander can issue a reset without disconnecting the RTT viewer.

    So instead of running nrfjprog in a terminal, open J-Link commander and issue a reset there.

  • Related