nrf52832 SDK12 RTT Logger Module Issue

I'm having an issue getting strings to print properly using the RTT and the logging module. Literal strings seem to work fine. I.E. the following works perfectly:

NRF_LOG_INFO("Test\r\n");

I want to use non-literal strings. For example, the code in this guide doesn't work for me. Specifically I try to run the code:

void foo(void)
{ 
    char string_on_stack[] = "stack";
    //nrf_log_push() copies the string into the logger buffer and returns address from the logger buffer
    NRF_LOG_INFO("%s",nrf_log_push(string_on_stack));
}

but in the RTT Viewer it shows up as "s" (i.e. it is literally printing the s from "%s"). Other format specifiers work properly (like %d).

I have copied the source files SEGGER_RTT_Syscalls_KEIL.c, SEGGER_RTT.c, and SEGGER_RTT_printf.c to the project.

If I include "SEGGER_RTT.h" in my file (which I dont think I should have to do) I can use SEGGER_RTT_printf and it shows up properly in RTT_Viewer.

I am wondering if somehow NRF_LOG_INFO isnt being routed into SEGGER_RTT_printf as I would expect.

In the project level defines in Keil I have defined NRF_LOG_USES_RTT=1

The relevant part of my sdk_config is here:

// <h> nRF_Log

//==========================================================
// <e> NRF_LOG_ENABLED - nrf_log - Logging
//==========================================================
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 1
#endif
#if  NRF_LOG_ENABLED
// <e> NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string
//==========================================================
#ifndef NRF_LOG_USES_COLORS
#define NRF_LOG_USES_COLORS 0
#endif
#if  NRF_LOG_USES_COLORS
// <o> NRF_LOG_COLOR_DEFAULT  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRF_LOG_COLOR_DEFAULT
#define NRF_LOG_COLOR_DEFAULT 0
#endif

// <o> NRF_LOG_ERROR_COLOR  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRF_LOG_ERROR_COLOR
#define NRF_LOG_ERROR_COLOR 0
#endif

// <o> NRF_LOG_WARNING_COLOR  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRF_LOG_WARNING_COLOR
#define NRF_LOG_WARNING_COLOR 0
#endif

#endif //NRF_LOG_USES_COLORS
// </e>

// <o> NRF_LOG_DEFAULT_LEVEL  - Default Severity level

// <0=> Off
// <1=> Error
// <2=> Warning
// <3=> Info
// <4=> Debug

#ifndef NRF_LOG_DEFAULT_LEVEL
#define NRF_LOG_DEFAULT_LEVEL 3
#endif

// <e> NRF_LOG_DEFERRED - Enable deffered logger.

// <i> Log data is buffered and can be processed in idle.
//==========================================================
#ifndef NRF_LOG_DEFERRED
#define NRF_LOG_DEFERRED 1
#endif
#if  NRF_LOG_DEFERRED
// <o> NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words.
// <i> Must be power of 2

#ifndef NRF_LOG_DEFERRED_BUFSIZE
#define NRF_LOG_DEFERRED_BUFSIZE 256
#endif

#endif //NRF_LOG_DEFERRED
// </e>

// <q> NRF_LOG_USES_TIMESTAMP  - Enable timestamping


// <i> Function for getting the timestamp is provided by the user

#ifndef NRF_LOG_USES_TIMESTAMP
#define NRF_LOG_USES_TIMESTAMP 0
#endif

#endif //NRF_LOG_ENABLED
// </e>

// <h> nrf_log_backend - Logging sink

//==========================================================
// <o> NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string
// <i> Logger backend RAM usage is determined by this value.

#ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH
#define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256
#endif

// <o> NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp
// <i> If higher resolution timestamp source is used it might be needed to increase that

#ifndef NRF_LOG_TIMESTAMP_DIGITS
#define NRF_LOG_TIMESTAMP_DIGITS 8
#endif

// <q> NRF_LOG_BACKEND_SERIAL_USES_RTT  - If enabled data is printed using RTT


#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT
#define NRF_LOG_BACKEND_SERIAL_USES_RTT 1
#endif

// </h>
//==========================================================

As another example, if I run the code:

    char string_on_stack[] = "stack";
    int my_num = 3;
    
    NRF_LOG_INFO("Literal\n");
    NRF_LOG_PROCESS();
    
    NRF_LOG_INFO("my_num is %d\n", my_num);
    NRF_LOG_PROCESS();

    NRF_LOG_INFO("%s\n",nrf_log_push(string_on_stack));
    NRF_LOG_PROCESS();
    
    NRF_LOG_INFO("%s\n",(uint32_t)string_on_stack);
    NRF_LOG_PROCESS();
    
    SEGGER_RTT_printf(0,"%s\n", string_on_stack);

the result will be:

image description

I am hoping I am just missing a define or something like that as I'd like to use the NRF_LOG macros.

Thanks!

  • It seems to be working here. I just took ble_app_hrs, set NRF_LOG_ENABLED 1 and NRF_LOG_BACKEND_SERIAL_USES_RTT 1 and put

    char string_on_stack[] = "stack";
    //nrf_log_push() copies the string into the logger buffer and returns address from the logger buffer
    NRF_LOG_INFO("%s",nrf_log_push(string_on_stack));
    

    in main(). Then I get:

     0> SDH:INFO:sd_ble_enable: RAM START at 0x20002128
     0> APP:INFO:Heart Rate Sensor Start!
     0> APP:INFO:Fast Adverstising
     0> APP:INFO:stack
    
  • Thank you for your response and sorry for the delay in my reply.

    I notice that MicroLib is enabled in ble_app_hrs. Does it still work for you if MicroLib is disabled? I get the same result as you if MicroLib is enabled (it works) but it stops working when I disable it.

    This suggests to me that the SEGGER_RTT_printf.c isnt being used. I cannot use MicroLib in my project for various reasons (and I was under the impression I wouldnt need to use it)

  • It does not work if MicroLib is disabled, so I guess this is a limitation of the standard library which is used when MicroLib is not used. No, I don't think SEGGER_RTT_printf.c is being used.

  • Looking at the source of SEGGER_RTT_printf.c, it seems to do what I want (it looks like it would print strings using the %s specifier properly) I'm not sure how to make it use SEGGER_RTT_printf though.

    This tutorial: devzone.nordicsemi.com/.../ suggests that this should work without MicroLib (it says: uncheck "Use MicroLIB" and add SEGGER_RTT_printf.c).

    I seem to be able to compile and run the project without even including SEGGER_RTT_printf.c with no difference at all. Placing breakpoints show that SEGGER_RTT_printf doesn't get called.