2019-01-20 06:16 PM
Hello,
I've spent quite a bit of time scratching my head and I would appreciate any guidance in this matter.
I am using Segger's Embedded Studio with Segger's RTT printf library. Everything works fine with the Segger_RTT_printf() output. I can see the output it in the terminal, no issue.
Segger also provides a SEGGER_RTT_Syscalls.c which implements the following so I can overload printf() function:
#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM)
#include <reent.h> // required for _write_r
#include "SEGGER_RTT.h"
struct _reent;
int _write(int file, char *ptr, int len);
int _write_r(struct _reent *r, int file, const void *ptr, size_t len);
int _write(int file, char *ptr, int len) {
(void) file; /* Not used, avoid warning */
SEGGER_RTT_Write(0, ptr, len);
return len;
}
int _write_r(struct _reent *r, int file, const void *ptr, size_t len) {
(void) file; /* Not used, avoid warning */
(void) r; /* Not used, avoid warning */
SEGGER_RTT_Write(0, ptr, len);
return len;
}
#endif
I can compile and link OK. But, when I debug, the printf() function never calls my custom _write() function.
Instead, the debugger jumps to the following disassembly:
<iprintf>
<printf>
B40F push {r0-r3}
4B0A ldr r3, =0x20000080 <_impure_ptr>
B513 push {r0-r1, r4, lr}
681C ldr r4, [r3]
B124 cbz r4, 0x0802E1EC
69A3 ldr r3, [r4, #24]
B913 cbnz r3, 0x0802E1EC
4620 mov r0, r4
F7FFFE00 bl 0x0802DDEC <__sinit>
AB05 add r3, sp, #20
9A04 ldr r2, [sp, #16]
68A1 ldr r1, [r4, #8]
9301 str r3, [sp, #4]
4620 mov r0, r4
F000FC4D bl 0x0802EA94 <_vfiprintf_r>
B002 add sp, sp, #8
E8BD4010 pop.w {r4, lr}
B004 add sp, sp, #16
4770 bx lr
20000080 .word 0x20000080
How can I can link it properly? I am using GCC ARM compiler version 8.0.
Thank you!
Solved! Go to Solution.
2019-01-20 07:36 PM
I have managed to fix this issue by changing the linker from arm-eabi-none-g++ to arm-eabi-none-gcc.
These options can be found in your Project Options > Code > External Build inside Segger Embedded Studio.
In retrospect, this was pretty obvious that the linker was not linking newlib/gcc stdlib and was not able to overload _write() and _write_r() custom functions inside of SEGGER_RTT_GCC_Syscalls.c
Hope this helps!
2019-01-20 07:36 PM
I have managed to fix this issue by changing the linker from arm-eabi-none-g++ to arm-eabi-none-gcc.
These options can be found in your Project Options > Code > External Build inside Segger Embedded Studio.
In retrospect, this was pretty obvious that the linker was not linking newlib/gcc stdlib and was not able to overload _write() and _write_r() custom functions inside of SEGGER_RTT_GCC_Syscalls.c
Hope this helps!
2021-08-25 06:06 PM
@Spectramax answer is incomplete.
If C compiler is used then declaration below would be sufficient
int _write(int file, char *ptr, int len) {
(void) file; /* Not used, avoid warning */
SEGGER_RTT_Write(0, ptr, len);
return len;
}
But when it comes to C++ compiler, then all names are mangled and linker is unable to match the symbol. So in essence extern "C" declaration needs to be used. Wrap it into proper #ifdefs or other fluff.
Minimal working version:
extern "C" int _write(int file, char *ptr, int len) {
(void) file; /* Not used, avoid warning */
SEGGER_RTT_Write(0, ptr, len);
return len;
}