STM32 printf() redirect
... how to re-direct printf(). I have read multiple sources that I need to.
You only need to retarget the library if you are using the functions that require retargeting (printf()
being one of them).
- What exactly does
__FILE
do? I do not see it used?
In this case, nothing; it just needs to be there to conform to the standard library stdio function signatures. And resolve references to FILE
type objects (such as stdout
in the standard library).
If you were to support multiple stream devices, then this structure would be needed and could be customised.
- Why does
__stdout
have two '_' before it?
Because it is a compiler/system reserved symbol and that is the convention defined for such symbols by the ISO C standard. Internally the library references the stdout stream through that symbol, but does not instantiate it - that is what your retargeting layer does, so it is necessary to define it for the library to link.
- Why is the
FILE
typedef'd data type get assigned to__stdout
?
See (2) above.
The standard streams are stdout, stdin and stderr, printf
outputs to stdout, (essentially printf()
is a wrapper around fprintf()
but with the FILE
parameter implicitly being the pre-defined stdout
stream; this is where that predefined stream is instantiated.
- Does code need to be added to
/* Your implementation of fputc(). */
?
That is what the comment suggests! It is the only function you need to explicitly implement to support printf()
. If for example you already have serial I/O code to output to the UART, a minimalist implementation that would work is:
int fputc(int ch, FILE *f)
{
f = f ; // unused warning prevention
uartOutCh( ch ) ; // your character output function.
return ch;
}
It is as simple as that - all the FILE
, __stdout
stuff etc is important only if you need to implement full support for stdio with multiple stream devices I/O devices that can be opened using fopen()
for example. They do need to at least exist in these minimal implementations however because the standard library references them and will not link if they are missing (although there are possibly weak-link implementations in the library that are used if no alternative implementation exists).
The basics of retargeting the C library are described at http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0378g/chr1358938930366.html.
More sophisticated retargetting implementations including UART support are described at http://www.keil.com/pack/doc/compiler/RetargetIO/html/index.html. A great deal of out-of-the box support via "DevPacks" is available for a number iof targets. It is perhaps a lot simpler that it used to be with earlier versions of uVision/MDK-ARM where you were more-or-less on your own; I have not tried the DevPacks methods described since I have been using the ARM-MDK and STM32 for a long time since before all that support was provided.
Hart22
Updated on June 13, 2022Comments
-
Hart22 almost 2 years
I have a STM32VL Discovery board, which uses the STM32F100RB microcontroller. I am using Keil uVision 5.24.2.0. I am using the compiler option 'ARM compiler 'Use default compiler version 5''.
I am trying to figure out how to use/redirect the
printf()
function on it.I understand the UART initialisation process, but I am really struggling to understand how to re-direct
printf()
. I have read multiple sources that I need to.Consider the following example at http://www.keil.com/forum/60531/:
#include <stdio.h> struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef’d in stdio.h. */ FILE __stdout; int fputc(int ch, FILE *f) { /* Your implementation of fputc(). */ return ch; } int ferror(FILE *f) { /* Your implementation of ferror(). */ return 0; } void test(void) { printf("Hello world\n"); }
- What exactly does
__FILE
do? I do not see it used. - Why does
__stdout
have two '_'s before it? - Why is the
FILE
typedef'd data type get assigned to__stdout
? - Does code need to be added to
/* Your implementation of fputc(). */
?
-
Admin over 6 yearsRedirect it to what?
-
0___________ over 6 yearsSorry - deleted my answer as I do not use Keil and Keil libraries.
-
0___________ over 6 years@duskwuff does it matter?
-
Admin over 6 years@PeterJ Yes! If the OP wants to redirect
printf()
to semihosted I/O, for instance, there's a specific procedure to accomplish that which would be different from directing it to a USART or whatnot. -
Hart22 over 6 yearsI am trying to redirect it to a USART port, which I am going to connect to my PC through a UART to USB converter.
-
0___________ over 6 yearsTo redirect to anything there are some steps too. But the general idea is the same.
-
0___________ over 6 yearsgoogle keil printf redirection uart - you have 100s instructions and ready examples
-
old_timer over 6 yearseasier to avoid printf, second easiest is to find a printf designed for this kind of work, that doesnt have such a heavy system backend.
- What exactly does
-
Hart22 over 6 yearsThank you very much for this detailed answer, very informative and useful!