The world is changing, and the say is “change is good” :-). In the software and API world, change very often means that a change results into something broken. So I had battled with semihosting working on the NXP Kinetis parts, only to find out that it does not work any more with using the latest version 2.0. The semihosting output e.g. with P&E debug connection remains empty:
So how to fix this?
Guess I need to embrace change (see Dilbert on that topic 😉 )?
In my project I’m using the project I had created for the FRDM-KL27Z with the NXP Kinetis Design Studio using the GNU ARM Eclipse plugins (see “Tutorial: Blinky with the FRDM-KL27Z and Kinetis SDK v2“).
So here is how to use Semihosting with a Kinetis SDK V2.0 project: In the linker settings, replace the ‘-specs=nosys.specs’ with ‘specs=rdimon.specs’:
In the debug configuration settings, have semihosting enabled:
Settings for P&E:
Settings for Segger:
Settings for OpenOCD:
Now all what I need in my application is to include the header file for printf():
#include <stdio.h>
And use printf() to say hello to the world:
printf("hello world!\r\n");
So far everything is pretty ‘standard’ (see my previous articles on this subject in the ‘Links’ section at the end of this article). With the Kinetis SDK v1.3 for example I would get it correctly:
But with the SDK v2.0 nothing happens :-(:
So what is the problem?
The problem are these linker options which are present for a SDK v2.0 project which need to be removed:
-Xlinker -z -Xlinker muldefs
So what are these options doing? They tell the linker to let the application overwrite functions of the ANSI library. This is what ‘muldefs’ does: it allows multiple definitions of functions. So if I link now the application with the option removed, I get linker errors:
So the problem is that the Kinetis SDK V2.0 overwrites in fsl_debug_console.c the standard library _read() and _write() functions :-(. So this is why semihosting stopped working with the SDK v2.0: because the SDK is using the low-level read/write functions for their own implementation of printf(), it breaks with the needs of semihosting. And most (if not all?) Kinetis SDK v2.0 example project and templates come with that fsl_debug_console file :-(.
With this knowledge an obvious workaround is to remove the fsl_debug_console.c from the application. Or rename the _write() and _read() functions so there is no linker conflict.
With the functions removed/renamed, I can now link again. And semihosting works again 🙂
Summary
To use semihosting, I need to change the linker option -specs=nosys.specs to -specs=rdimon.specs. In the debug/launch configuration I need to have semihosting enabled. Because NXP Kinetis SDK V2.0 projects overwrite the _read() and _write() standard functions, I need remove the -Xlinker -z -Xlinker muldefs linker option and have the _read() and _write() functions in fsl_debug_console.c renamed/removed. With this semihosting works again with Kinetis SDK V2.0 projects :-).
Links
- Why you should not use printf(): https://mcuoneclipse.com/2013/04/19/why-i-dont-like-printf/
- Blinky for the FRDM-KL27Z: Tutorial: Blinky with the FRDM-KL27Z and Kinetis SDK v2: https://mcuoneclipse.com/2016/03/13/tutorial-blinky-with-the-frdm-kl27z-and-kinetis-sdk-v2/
- Semihosting for KDS v3.0.0 and GNU ARM Embedded (launchpad): https://mcuoneclipse.com/2015/05/27/semihosting-for-kinetis-design-studio-v3-0-0-and-gnu-arm-embedded-launchpad/
- Semihosting with GNU ARM Embedded (launchpad): https://mcuoneclipse.com/2015/04/23/semihosting-with-gnu-arm-embedded-launchpad-and-kinetis-design-studio/
- Semihosting with KDS V2.0.0: https://mcuoneclipse.com/2014/06/06/semihosting-with-kinetis-design-studio/
- Semihosting with KDS V2.0.0 and GNU ARM Embedded (launchpad): https://mcuoneclipse.com/2014/09/11/semihosting-with-gnu-arm-embedded-launchpad-and-gnu-arm-eclipse-debug-plugins/
- Printf() and scanf() with GNU ARM Libraries: https://mcuoneclipse.com/2014/07/11/printf-and-scanf-with-gnu-arm-libraries/
A few things:
1. fsl_sbrk.c also gets in the way, redefining _sbrk.
2. You can’t remove fsl_debug_console.c because fsl_common.c and the basic board.c depend on it:
./drivers/fsl_common.o: In function `__assert_func’:
F:\Google Drive\workspace.kds\blinky\Debug/../drivers/fsl_common.c:47: undefined reference to `DbgConsole_Printf’
./board/board.o: In function `BOARD_InitDebugConsole’:
F:\Google Drive\workspace.kds\blinky\Debug/../board/board.c:40: undefined reference to `DbgConsole_Init’
So I renamed _read to _read_fsl and _write to _write_fsl.
3. Even after following your instructions (replacing nosys with rdimon, removing -Xlinker -z -Xlinker multidefs) I got no output. The only differences I can see between my setup and yours is:
a. I am using a FRDM-KL64F.
b. I simply added #include and one printf in the empty project provided when you start a new Kinetis SDK 2.x project.
c. It is August 2016, and I updated all the plugins. Maybe semihosting broke again?
LikeLike
Hi Robert,
yes, in my view semihosting is broken again in the SDK. As for your point 2): I’m not using the fsl_debug_console and printf for good reasons (see https://mcuoneclipse.com/2013/04/19/why-i-dont-like-printf/). I avoid this kind of things and kick out such printf() calls out of the demos and applications as they are really bad.
c) Semihosting should not depend on any plugins.
Let me see if I find time to check with the FRDM-K64F.
LikeLike
Hi Robert,
I hope this new article helps:
https://mcuoneclipse.com/2016/08/06/semihosting-again-with-nxp-kinetis-sdk-v2-0/
Erich
LikeLike
Pingback: Semihosting (again!) with NXP Kinetis SDK V2.0 | MCU on Eclipse
Hi Erich,
you said
“Remove the fsl_debug_console.c from the application. Or rename the _write() and _read() functions so there is no linker conflict.”
I removed fsl_debug_console.c from application then also semihost is not working, it is showing blank.
Where and how to rename _write() and _read()?
I want data on UART, can I catch this printf data on UART also?
LikeLike
Hi Syed,
Please see this new post on that topic: https://mcuoneclipse.com/2016/08/06/semihosting-again-with-nxp-kinetis-sdk-v2-0/.
Yes, you can use UART to printf() data to it, this is what fsl_debug_console.c is doing.
I hope this helps,
Erich
LikeLike