I'm writing a program to run on an ATmega328p - bare avr-libc rather than Arduino, though it does use the Arduino bootloader over serial (I don't imagine that affects the following question though).
I have set up stdout to write to the UART in the hopefully-obvious manner:
void uart_putc(char c)
{
// Turn LFs into CRLFs
if(c == '\n')
uart_putc('\r');
while(!(UCSR0A & _BV(UDRE0)))
;
UDR0 = c;
}
static int _putc(char c, FILE *_)
{
uart_putc(c);
return 0;
}
...
fdev_setup_stream(stdout, &_putc, NULL, _FDEV_SETUP_WRITE);
If I now write my program using only fputc and fputs then all works fine. I can even call snprintf() to render formatted strings into a char buffer[16] and then fputs() them out; these things all work fine.
fputs("Hello, world\n", stdout); /* works fine */
char buffer[16];
snprintf(buffer, sizeof buffer, "Hello, %s\n", "world");
fputs(buffer, stdout); /* also works fine */
However, the moment I try to perform a real fprintf() to stdout the program crashes and reboots the ATmega:
fprintf(stdout, "Hello, %s\n", "world");
It crashes immediately, before even outputting the initial H here.
Can anyone suggest something that might be missing, that would stop fprintf() working, when both snprintf() and fputs() can work fine?
fprintf, and "walk" the disassembly until a crash occurs. Then do it again, and just before executing the instruction that causes the crash, open a register-view, copy all the registers, and publish them here. In addition, publish the instruction that causes the crash. This might provide us with some significant piece of information. BTW, you can do the same withfputsand see for yourself how come one is working and the other one isn't working. - barak manos