Hello, Is it possible to get logs (RTT) from an application started by a bootloader? As of now I don't get anything after the bootloader has jumped to the application start address.
If I run the application separately it works.
Thanks, Jacob
Hello, Is it possible to get logs (RTT) from an application started by a bootloader? As of now I don't get anything after the bootloader has jumped to the application start address.
If I run the application separately it works.
Thanks, Jacob
Hi Jacob,
If you have a look here at the section on how RTT work. You can find that it was not the different channel caused the problem, it's the different allocation of RAM area for the RTT Control Block and the RTT buffer location caused the problem.
If we match the Control Block address and the RTT buffers location the same on the bootloader and the application, then everything works.
This is the modification I did to SEGGER_RTT.c from line 135:
static char _acUpBuffer [BUFFER_SIZE_UP] __attribute__((at(0x20003C00)));
static char _acDownBuffer[BUFFER_SIZE_DOWN]__attribute__((at(0x20003F00))); ;
//
// Initialize SEGGER Real-time-Terminal control block (CB)
//
SEGGER_RTT_CB _SEGGER_RTT __attribute__((at(0x20002C00)));
I used attribute to force the linker to put the buffer is defined location. You don't have to use the same addresses, it can be any where in RAM (of course in the application RAM range).
For anyone encountering this problem now, since at least SDK 16 (haven't looked back further), you can simply define a few macros in your app/sdk_config.h:
#define SEGGER_RTT_ALIGNMENT 4 #define SEGGER_RTT_BUFFER_ALIGNMENT 4 #define SEGGER_RTT_SECTION ".rtt_cb" #define SEGGER_RTT_BUFFER_SECTION ".rtt_buffers"
and add the corresponding sections to your linker files:
MEMORY { ... /* Put RTT data at top of RAM. */ /* RTT_CB LENGTH = 24 + SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS * 24 + SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS * 24 */ RTT_CB (rw) : ORIGIN = 0x2003ff88, LENGTH = 0x78 /* RTT_BUFFERS LENGTH = + SEGGER_RTT_CONFIG_BUFFER_SIZE_UP + SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN */ /* RTT_BUFFERS ORIGIN = 0x20040000 - CB LENGTH - BUFFERS LENGTH */ RTT_BUFFERS (rw) : ORIGIN = 0x2003ef78, LENGTH = 0x1010 } SECTIONS { .rtt_buffers : { KEEP(*(.rtt_buffers)) } > RTT_BUFFERS .rtt_cb : { KEEP(*(.rtt_cb)) } > RTT_CB }
I've implemented implemented in such way but my RTT does not starts
As I see differences from original implementation - a load address is not specified for both sections ( top part )
- top part is original rtt location
- bottom part is custom rtt location
.igot.plt 0x00000000200051f4 0x0 load address 0x0000000000041528 .igot.plt 0x00000000200051f4 0x0 toolchain/gcc-arm-none-eabi-10-2020-q4-major/bin/../lib/gcc/arm-none-eabi/10.2.1/thumb/v7e-m+fp/hard/crtbegin.o .rtt_buffers 0x00000000200051f4 0x210 load address 0x0000000000041528 .rtt_buffers 0x00000000200051f4 0x210 /tmp/nrf52840_xxaa.out.22h15i.ltrans0.ltrans.o .rtt_control_block 0x0000000020005404 0x78 load address 0x0000000000041738 .rtt_control_block 0x0000000020005404 0x78 /tmp/nrf52840_xxaa.out.22h15i.ltrans0.ltrans.o 0x000000002000547c . = ALIGN (0x4) .igot.plt 0x00000000200051f4 0x0 load address 0x0000000000041528 .igot.plt 0x00000000200051f4 0x0 toolchain/gcc-arm-none-eabi-10-2020-q4-major/bin/../lib/gcc/arm-none-eabi/10.2.1/thumb/v7e-m+fp/hard/crtbegin.o .rtt_buffers 0x000000002003fd78 0x210 *(.rtt_buffers) .rtt_buffers 0x000000002003fd78 0x210 /tmp/nrf52840_xxaa.out.SzFaPv.ltrans0.ltrans.o .rtt_control_block 0x000000002003ff88 0x78 *(.rtt_control_block) .rtt_control_block 0x000000002003ff88 0x78 /tmp/nrf52840_xxaa.out.SzFaPv.ltrans0.ltrans.o 0x0000000020040000 . = ALIGN (0x4)
please advise
I discovered a couple of things:
The RTT control block must be zeroed out before RTT's init is called (it doesn't zero it's special memory block, but the RTT tools expect it to be zeroed aside from its special bytes).
Sometimes the RTT tools can take a while to find the memory block, but you can create a jlink script to help them:
/* set_RTT_location.jlinkscript */ /* Command-line options: -nogui -select USB -device nRF52840_xxAA -if SWD -endian little -speed 4000 -jlinkscriptfile path/to/set_RTT_location.jlinkscript */ /* Alternatively, run command from gdb CLI: eval "monitor exec SetRTTAddr %p", &_SEGGER_RTT */ int SetupTarget(void) { JLINK_ExecCommand("SetRTTAddr 0x2003EF78"); }
Thanks for quick reply but no result for now
BTW SDK v17.0.2, JLink toolset 6.88
I also have these macros defined, with the above RTT macros, but I don't remember exactly why:
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4096 #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 #define SEGGER_RTT_ALIGNMENT 4 #define SEGGER_RTT_BUFFER_ALIGNMENT 4 #define SEGGER_RTT_SECTION ".rtt_cb" #define SEGGER_RTT_BUFFER_SECTION ".rtt_buffers"
I also added NOLOAD directives to my linker script (again, don't remember exactly why):
.rtt_buffers(NOLOAD) :
.rtt_cb(NOLOAD) :
Let me know if one of those works and I'll update my previous post.
I also have these macros defined, with the above RTT macros, but I don't remember exactly why:
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4096 #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 #define SEGGER_RTT_ALIGNMENT 4 #define SEGGER_RTT_BUFFER_ALIGNMENT 4 #define SEGGER_RTT_SECTION ".rtt_cb" #define SEGGER_RTT_BUFFER_SECTION ".rtt_buffers"
I also added NOLOAD directives to my linker script (again, don't remember exactly why):
.rtt_buffers(NOLOAD) :
.rtt_cb(NOLOAD) :
Let me know if one of those works and I'll update my previous post.