【发布时间】:2023-03-07 20:35:01
【问题描述】:
我正在编写一个在 ATmega328p 上运行的程序 - 裸 avr-libc 而不是 Arduino,尽管它确实使用 Arduino 引导加载程序而不是串行(我不认为这会影响以下问题)。
我已设置 stdout 以希望显而易见的方式写入 UART:
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);
如果我现在只使用fputc 和fputs 编写程序,那么一切正常。我什至可以调用snprintf() 将格式化的字符串呈现为char buffer[16],然后将fputs() 输出;这些东西都可以正常工作。
fputs("Hello, world\n", stdout); /* works fine */
char buffer[16];
snprintf(buffer, sizeof buffer, "Hello, %s\n", "world");
fputs(buffer, stdout); /* also works fine */
但是,当我尝试执行真正的 fprintf() 到 stdout 时,程序崩溃并重新启动 ATmega:
fprintf(stdout, "Hello, %s\n", "world");
它立即崩溃,甚至在此处输出初始 H 之前。
当snprintf() 和fputs() 都可以正常工作时,任何人都可以提出一些可能会导致fprintf() 停止工作的东西吗?
【问题讨论】:
-
你可能会看看是否有一个带有调试器的模拟器,你可以在上面运行它。
-
进入
fprintf,并“走”反汇编直到发生崩溃。然后再做一次,就在执行导致崩溃的指令之前,打开一个寄存器视图,复制所有寄存器,并在此处发布它们。此外,发布导致崩溃的指令。这可能会为我们提供一些重要的信息。顺便说一句,您可以对fputs执行相同的操作,并亲眼看看一个如何工作而另一个不工作。 -
与任何 printf 函数相关的崩溃让我想到了堆栈溢出。尝试增加堆栈大小。
标签: c microcontroller avr libc