Kristin gravatar image

Posted 2015-04-08 11:06:34 +0100

Debugging with Real Time Terminal

This tutorial will show how to use RTT debugging

In SDK 12.0.0 or later, logging/debugging over RTT is built in to the logger module NRF_LOG. To enable logging over RTT, "check" the NRF_LOG_BACKEND_SERIAL_USES_RTT option in sdk_config.h in the configuration wizard.

This tutorial is therefore mostly relevant for SDK 11 or older.

Normally when creating software there is a need to debug and monitor the execution of the code. There are several options when it comes to debugging, for example printing information on the serial port, or using breakpoints and stepping through the code in Keil. However, these methods don't work very well when debugging real-time critical applications like bluetooth applications. A good alternative to standard logging on the serial port is to use the Real Time Terminal from SEGGER. This tutorial will show how this debug feature can be added to any existing project.

Requirements



Adding RTT files to project

As with the previous tutorials, this tutorial will be based on the ble_app_uart project, but any other project can be used.

  • Open the ble_app_uart example as explained in tutorial 1

  • Download the zip file with the required RTT files as linked above, and unzip it

  • Copy the RTT and Syscalls folder from the zip file into C:\Keil_v5\ARM\Pack\NordicSemiconductor

  • In Keil, go to Project -> Options for target

  • In the C/C++ tab, add C:\Keil_v5\ARM\Pack\NordicSemiconductor\RTT to the include path

  • Include SEGGER_RTT.h to the project by writing #include "SEGGER_RTT.h" near the top of the main.c file in the project

Now we have the header file for the RTT functions but we also have to add the .c files to the project.

  • In Keil, right-click on the project-folder and click Add Group. Name it RTT

  • Right click on the new group and select Add existing files to group 'RTT'

  • Navigate to C:\Keil_v5\ARM\Pack\NordicSemiconductor\RTT and add SEGGER_RTT.c

You should now be able to send simple strings through the RTT interface. In the main function in the main file, add the following line right before the main loop:

SEGGER_RTT_WriteString(0, "Hello World!\n");

The first argument is which channel to write the text to. You can read more about channels on the SEGGER webapge, but the default channel is 0. Compile the code to make sure everything went ok.



Opening a Real Time Terminal

Now that the code is sending output to our RTT, we have to be able to read it. There are several ways this can be done, as summarized on the segger webpage. The easiest way is to use the J-Link RTT Viewer that comes with the J-link software package.

  • Open J-Link RTT Viewer. You will then see the image below. If you have more than one device connected, check "Serial no." and enter the serial number of the device you wish to connect to.

image description

  • Click Ok. The screen below will then appear.

image description

Now, load the code you compiled above onto your device, and you should see the text "Hello World!" appear. Notice if you open Termite you will also see the text "Start.." which is still printed on the serial port as before. You can now use the ble_app_uart project as intended, but also send text to RTT in order to debug. Keep in mind that SEGGER_RTT_WriteString() is much faster than printf, so you can safely call this function without it affecting the real time properties of your application.



Sending text to target

You can also use RTT to send text to your device, as an alternative to UART. Modify the main loop in the ble_app_uart project so it looks like below. Remember to also include nrf_delay.h to use the delay function.

char c = 0;
for (;;)
{
    c = SEGGER_RTT_WaitKey(); // will block until data is available
    if(c == 'r'){
        SEGGER_RTT_WriteString(0, "Resetting..\n");
        nrf_delay_ms(1000);
        sd_nvic_SystemReset();
    }
    //power_manage();
}
  • Compile and flash the code onto the device

  • In RTT Viewer, go to Input -> Sending and click Send on Enter. (Otherwise it sends on every key you press, which can be annoying)

  • Write an 'r' in the textfield and hit enter. You should now see the board resetting.

image description

image description



More advanced printing

So far we have only looked at unformatted printing, using SEGGER_RTT_WriteString(). A more powerful function is the SEGGER_RTT_printf() function. To be able to use it, we must modify the project a bit more.

  • Add the file SEGGER_RTT_printf.c to the project, just like you added SEGGER_RTT.c above

  • In the same way, add RTT_Syscalls_KEIL.c, from C:\Keil_v5\ARM\Pack\NordicSemiconductor\Syscalls

  • Right-click nRF_Libraries and click Options

image description

  • In the list of Software Components, click retarget, and then the remove-button

image description

  • Now go to Project -> Options for target, and uncheck "Use MicroLIB"

image description

  • Edit the main loop so it looks like below:
char c = 0; 
for (;;) {
    c = SEGGER_RTT_WaitKey(); // will block until data is available
    if(c == 'r'){
        SEGGER_RTT_printf(0, "%sResetting in %d second..%s\n", RTT_CTRL_BG_BRIGHT_RED, 1, RTT_CTRL_RESET);
        nrf_delay_ms(1000);
        sd_nvic_SystemReset();
    }
    //power_manage();
}

Compile and run the project. Notice that the output can be color-coded to allow for a visually appealing debug output. In RTT-viewer, go to Terminal 0 to see the colored output.

image description

Notice that the printf function also directs its output to RTT now. The ble_app_uart project will still work as intended though, because it uses app_uart_put which outputs to the serial port.

An example on how to use the printf function:

SEGGER_RTT_printf(0, "variable value: %d\n", variable);

where the first parameter specifies that the output should be printed to Terminal 0 in the J-Link RTT Viewer, second parameter is the string to print, and the value of "variable" is inserted for "%d"

For more information on RTT and the various functions, you can read more in chapter 10 in the J-Link manual.

26 comments

mubbasher gravatar image

Posted April 27, 2015, 9:48 a.m.

Hi I tried this... But when I open RTT Log Viewer, It show this message:

Could not connect RTT Viewer. RTT Viewer will be closed now.

do you have any idea why is it so ?

vebjornr gravatar image

Posted April 29, 2015, 1 p.m.

Yes, the RTT Logger doesn't quite work, I have tried to ask Segger if there are any faults with it. If you only stick with RTT Viewer, you should be OK. If you get the error, simply try resetting the board and opening RTT Viewer again. Make sure the board is connected and the application is running.

muhkuhns gravatar image

Posted May 7, 2015, 3:25 p.m.

Maybe I am blind, but I can't seem to find a way to let the text autoscroll like all other terminals do.. When the viewfield textarea is full I need to scroll to see the text that is added hidden at the bottom...

Maybe someone can name an alternative viewer?

kklobe gravatar image

Posted May 11, 2015, 7:47 p.m.

I've followed the procedure for "More advanced printing" but I stop getting output in RTT Viewer after printing BUFFER_SIZE_UP characters via printf.

However, the direct functions (e.g. SEGGER_RTT_printf) still work. I'm using Segger package v4.98e.

Has anyone else seen this behavior?

chuonghd gravatar image

Posted May 13, 2015, 10:05 p.m.

Been using this for a couple of days and so far it is my most favourite way for debugging when device is in BLE connection. For someone who wants a comparison with normal UART, RTT is far superior in terms of speed, hardware setup as well as memory usage.

By the way, I added some code for advanced printing stuffs without using SEGGER_RTT_printf.c. This code utilizes sprintf() function and you should include <stdio.h> to your project

#define RTT_PRINTF(...) \
do { \
     char str[64];\
     sprintf(str, __VA_ARGS__);\
     SEGGER_RTT_WriteString(0, str);\
 } while(0)

I used 64 bytes for the str char buffer, and this should be identical with BUFFER_SIZE_UP in SEGGER_RTT_Conf.h (1024 by default).

If you want to redirect printf function to my RTT_PRINTF, just add this macro:

#define printf RTT_PRINTF
tumaku gravatar image

Posted May 28, 2015, 11:57 a.m.

Very useful tutorial!.

Just one comment, please update the requirement list and remove keil as "mandatory". I have been able to use it to integrate RTT in my eclipse/gcc project (and I am really happy about it:)

Quick setup instructions in this other thread

Miladn gravatar image

Posted July 17, 2015, 8:07 a.m.

Hello, for some reason if I delete the retarget file I will get linking errors. Would this terminal work keeping the retarget.c? Thank You

image description

martial.britto gravatar image

Posted July 29, 2015, 7:54 a.m.

Hi I am trying to implement this debug mechanism in the dfu example on SDK 9.0. But i get an error like below. Could someone help on this?

c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: region RAM overflowed with stack

The above error occurs during compilation, if I add similar print statements shown below to code. There were no build error if those statements were commented. Also there were no errors because of the header and source files being included.

SEGGER_RTT_WriteString(0, "boot_main");

Thanks

oyvkar gravatar image

Posted July 29, 2015, 9:54 a.m.

Hi @martial,

I think your issue is related to using more RAM that you have available, please see this blogpost for more information.

Elm gravatar image

Posted Sept. 28, 2015, 5:29 p.m.

Hi,

Can I use RTT to build a CLI in the device? This would mean that the program would not block ( in function SEGGER_RTT_WaitKey() ), but wait for an event.

regards, Elk

Posted Oct. 29, 2015, 2:48 p.m.

Unable to have trace in bootloader by following our tutorial (it works well in application). Please, can someone help me ?

Regards,

hawkinchina gravatar image

Posted Nov. 17, 2015, 5:48 a.m.

hi,mobi:

  please running J-link Commander first, and make sure the connection is ok.. and then run RTT Viewer,  it will give message that  second debug session to the same j-link  detected, and  select

not change interface. RTT viewer will be OK.. enjoy it..

nikolaus gravatar image

Posted Feb. 1, 2016, 5:43 p.m.

A newer version of the RTT files are available by downloading the Windows Software and Documentation Pack from here. It looks like they may add them to the OS X S&D Pack as well, or break them out into a repo (source).

AB gravatar image

Posted Feb. 23, 2016, 11:14 p.m.

I am using SEGGER_RTT_WriteString to write a string but am unable to view it the RTT viewer. Program runs without a problem except I do not see the write string on the RTT viewer. Also the RTT viewer appears to have connected:

J-Link RTT Viewer V5.10d: Logging started. LOG: Global terminal added. LOG: Terminal 0 added. LOG: Device "NRF52832_XXAA" selected. LOG: Found SWD-DP with ID 0x2BA01477 LOG: Found Cortex-M4 r0p1, Little endian. LOG: FPUnit: 6 code (BP) slots and 2 literal slots LOG: CoreSight components: LOG: ROMTbl 0 @ E00FF000 LOG: ROMTbl 0 [0]: FFF0F000, CID: B105E00D, PID: 000BB00C SCS LOG: ROMTbl 0 [1]: FFF02000, CID: B105E00D, PID: 003BB002 DWT LOG: ROMTbl 0 [2]: FFF03000, CID: B105E00D, PID: 002BB003 FPB LOG: ROMTbl 0 [3]: FFF01000, CID: B105E00D, PID: 003BB001 ITM LOG: ROMTbl 0 [4]: FFF41000, CID: B105900D, PID: 000BB9A1 TPIU LOG: ROMTbl 0 [5]: FFF42000, CID: B105900D, PID: 000BB925 ETM LOG: RTT Viewer connected.

I suspect it is because the RTT control block is not being found. How do I verify this to be the case? And resolve this. Any pointers would be appreciated. Thanks!

TuongPV gravatar image

Posted April 5, 2016, 11:14 a.m.

Thank you very much. I was ported to iar and it works well.

simonlee gravatar image

Posted Aug. 25, 2016, 4:21 a.m.

If you encounter the below error message when compiling, "._build\nrf52832_xxaa_s132.axf: Error: L6218E: Undefined symbol SEGGER_RTT_printf (referred from main.o)."

add below define in ptions for target NRF_LOG_USES_RTT=1

if you use gcc compiler, add this define in your makefile. -DNRF_LOG_USES_RTT=1

adhenge gravatar image

Posted Oct. 29, 2016, 12:28 a.m.

Can anybody tell me why i am getting this error? I know i must be doing some silly mistake but i am unable to figure it out.

image description

i have included the (SEGGER_RTT.h) file in my main.c and have added all necessary files in project folder. am using keil

image description any help is appreciated.

adhenge gravatar image

Posted Oct. 29, 2016, 2:18 a.m.

I just missed the above comment. adding this "NRF_LOG_USES_RTT=1" in define worked. Thanks for the help.

usamak gravatar image

Posted Dec. 19, 2016, 8:20 p.m.

Is it possible to use RTT for debugging if the application also uses the serial port on the nRF52?

KorHacker gravatar image

Posted March 9, 2017, 7:04 a.m.

Thanks for this posting. it's very helpful me.

Brantel gravatar image

Posted March 15, 2017, 6:39 p.m.

I was getting linking errors like L6200E: when trying to follow this tutorial with version 13 of the SDK and current versions of KEIL and JLink.

Apparently the newer SDKs have built in support and you do not need to add the RTT group or the files to that group. If you do, remove them and it will get rid of these errors.

Posted April 10, 2017, 5:50 p.m.

I'm using sdk 11.0 with nRF51822 ... In order to use both UART and RTT, do I need to anything more? The sdhandler log seems to be printing okay, but anything sent to uart don't seem to disappear ...

Lola gravatar image

Posted May 4, 2017, 8:37 p.m.

and where is the J-Link RTT Viewer on a mac ? there is no such thing of course. Why are mac users treated as if they not exist ? mac is the future not pc. mac sales are raising and there are some people with taste that use mac, count them in ! :)

At least comment that this thing is not for mac.

nikolaus gravatar image

Posted May 4, 2017, 8:46 p.m.

You can use the terminal to view the RTT output on a Mac.

dsconyers gravatar image

Posted June 19, 2017, 9:10 p.m.

Does the nRF52 PCA10040 dev board support RTT?

I tried the following these instructions running SDK v13.0.0, but no luck.

"In SDK 12.0.0 or later, logging/debugging over RTT is built in to the logger module NRF_LOG. To enable logging over RTT, "check" the NRF_LOG_BACKEND_SERIAL_USES_RTT option in sdk_config.h in the configuration wizard."

whazin gravatar image

Posted Nov. 21, 2017, 4:58 p.m.

Hello:

I'm having a probem with the SEGGER_RTT_printf, it prints the folllowing message: e[4;41mResetting in 1 second..e[0m

I know the RTT_CTRL_BG_BRIGHT_RED is defined as "\e[4;41m". why isnt it able to resolve this? I do get warning when compiling

main.c(3280): warning: #192-D: unrecognized character escape sequence SEGGER_RTT_printf(0, "%sResetting in %d second..%s\n", TT_CTRL_BG_BRIGHT_RED, 1, RTT_CTRL_RESET);

while printfs and SEGGER_RTT_WriteString have no problems. Can someone please tell me why this is happening. Your time and effort is greatly appreciated. I'm using Keil

Thanks

Sign in to comment.

Related posts by tag