I have a real STM32F103ZE hardware which i program simple test printf redirect to STDOUT UART.
If i put printf("Test"); then it does not output anything until to UART until it reaches 64 bytes and then outputs.
If I put printf("Test\n"); then it instantly transmits to UART.
It seems adding the new line \n character seems to change the printf behavior.
I saw the ARM Compiler documents but it does not seems to be mentioned anywhere.
Can anyone comment on this?
What exactly does your redirection code look like? Using a USB VCP connection?
http://www.keil.com/support/man/docs/gsac/gsac_retargetcortex.htm
I am not doing any thing special was just following Tutorial in Keil ARM Document saying "Retarget Input and Output via UART"
There seems to be bug with Keil provided retarget_io.c
I had to modify fputc like below in my C file so problem is now resolved. Now putchar and printf works even for single characters, earlier it used to output only when it reaches 64 bytes.
It was nothing to do with PC buffer.
NEW
__weak int fputc (int c, FILE * stream) { return (stdout_putchar(c)); }
OLD Keil Provided code
__weak int fputc (int c, FILE * stream) { #ifdef RTE_Compiler_IO_STDOUT if (stream == &__stdout) { #if (STDOUT_CR_LF != 0) if (c == '\n') stdout_putchar('\r'); #endif return (stdout_putchar(c)); } #endif #ifdef RTE_Compiler_IO_STDERR if (stream == &__stderr) { #if (STDERR_CR_LF != 0) if (c == '\n') stderr_putchar('\r'); #endif return (stderr_putchar(c)); } #endif return (-1); }
"It was nothing to do with PC buffer."
Notice that I talk about generic printf() output and buffering. So nothing PC-specific, but something that exists outside of the embedded world. setbuf() and setvbuf() are part of the C standard, and controls buffering of FILE-based stream output which includes printf(), fprintf(), ...
When in full-buffer mode, you get data emitted when the buffer is full. In line-buffer mode, you get data emitted at end of strings. In unbuffered mode, every single character gets emitted.
Not sure what bug you think you found in Keils fputc function - it's quite common to have support for auto-translation of '\n' into "\r\n" line breaks, since that's the standard on the Windows platform. While the C language considers the single character '\n' to represent a line break.
The only thing is that most implementations who have such logic makes use of a stream-specific flag to check if fopen() did open the stream in binary or text mode. But in this specific case, the logic is hard-coded for stdout and stderr which are quite logical to be operating in text mode.
"at end of strings" should be "at end of lines".