This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Printf redirect to STDOUT

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?

  • You have similar issues on a PC - if you use full buffering, line buffering or unbuffered streams.

  • 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".

  • The following code should work:

    printf ("Test");
    fflush (stdout);