pico-sdk icon indicating copy to clipboard operation
pico-sdk copied to clipboard

following newline problem

Open Wirtos opened this issue 2 years ago • 2 comments

The code doesn't output anything via serial usb, but works in case fflush is there:

int main() {
    stdio_init_all();
    tusb_init();
    while (!tud_cdc_connected()) { sleep_ms(100); } 
    fprintf(stdout, "any string"); // same with fwrite
    // flush(stdout);
    puts(""); // print a newline
    return 0;
}

The following code also works fine:

int main() {
    stdio_init_all();
    tusb_init();
    while (!tud_cdc_connected()) { sleep_ms(100); } 
    fprintf(stdout, "any string\n");
    return 0;
}

Is the problem caused by some crt implementation detail? Host: Windows 11 Command: putty (plink -serial -sercfg 115200,8,n,1,N COM2)

Wirtos avatar Feb 09 '22 16:02 Wirtos

This isn't a bug, it's exactly how stdout is meant to work (same in Linux on a Raspberry Pi for example). It buffers the output unless either the buffer limit is reached, a new line character is sent, or it's manually flushed.

On the other hand, stderr immediately outputs without requiring a new line or flush, but to my knowledge stderr is currently not implemented yet in the Pico SDK.

On Linux, you can disable the buffering by setting the buffer to NULL like so: setbuf(stdout, NULL);, but I haven't tested if that works on the Pico or not. Though in generally you probably want the buffering, and manual flushing or adding new lines is the "correct" solution.

einsteinx2 avatar Mar 27 '22 21:03 einsteinx2

This isn't a bug, it's exactly how stdout is meant to work (same in Linux on a Raspberry Pi for example). It buffers the output unless either the buffer limit is reached, a new line character is sent, or it's manually flushed.

Stdout is line buffered, yes. As in the second example puts("") acts like printf("\n"), yet it doesn't flush for some reason and this snippet didn't output a thing when I tested (might be mistaken, don't have access to my pico rn)

fprintf(stdout, "any string"); 
puts(""); 
flush(stdout);

That's why I think there's a buffering issue. Will try to reproduce with a more obvious example on why it's broken IMO

Wirtos avatar Mar 27 '22 22:03 Wirtos

i read a similar issue recently that maybe puts/printf are using distinct buffering

kilograham avatar Feb 09 '23 15:02 kilograham

I'm having the same issue with fwrite() to stdio. The buffer being written must end with newline or it simply won't get written, unless it's followed by a manual fflush(). I would like to emphasize that this is not some PEBCAK issue with normal line buffering but an actual bug in the stdio implementation. The data is not buffered to be written later, it disappears.

Consider the following code

char buffer[] = "pico";

printf("Hi, my name is ");
int nmemb_written = fwrite(buffer, sizeof(buffer), 1, stdout);
assert(nmemb_written == 1);
printf("!\n");

On a functioning stdio implementation this outputs the expected Hi, my name is pico!

However, on the pico (I'm using serial over USB), it instead outputs Hi, my name is !

noname22 avatar Nov 15 '23 20:11 noname22