我正在尝试在树莓派上实现一个裸机应用程序,并希望将标准输出连接到迷你 uart 以进行调试。
我已按照此处和此处概述的流程进行操作
我创建了一个 uart_putc 函数,它似乎工作得很好,允许我将消息打印到我的 PC 的 COM 端口。然后我实现了 _write 系统调用,使其调用我的 uart_putc 函数进行输出。如果我将单个字符串文字传递给 printf 附加文字参数或任何非文字参数,则此方法工作正常,没有任何内容打印到串行端口,并且在几次调用后,应用程序挂起。
有谁知道可能出了什么问题?如果需要,很高兴提供更多信息...
void uart_putc(char c)
{
while(1)
{
if(aux[AUX_MU_LSR]&0x20) break;
led_blink(); // Blink the LED off then on again to
// make sure we aren't stuck in here
}
aux[AUX_MU_IO] = c;
}
...
int _write(int file, char* ptr, int len)
{
int todo;
for (todo = 0; todo < len; todo++)
{
uart_putc(*ptr++);
}
return len;
}
...
while(1)
{
printf("Hello World\r\n"); // Works
}
while(1)
{
printf("Hello %s\r\n", "World"); // This doesn't print anything
// and will hang after about five calls
}
char* s = (char*)malloc(sizeof(char) * 100); // Heap or stack it doesn't matter
strcpy(s, "Hello World\r\n");
while(1)
{
printf(s); // This doesn't print anything
// and will hang after about five calls
}
while(1)
{
for (i = 0; i < 13; i++)
{
uart_putc(s[i]); // Works
}
}
更新
我正在使用 newlib 并且 _write 在直接调用时可以正常工作。snprintf 似乎表现出同样的问题,即
snprintf(s, 100, "hello world\r\n"); // Works
snprintf(s, 100, "hello %s\r\n", "world"); // Doesn't work
我的 _sbrk 实现是从我的 OP 中引用的页面中删除的
char *heap_end = 0;
caddr_t _sbrk(int incr) {
extern char heap_low; /* Defined by the linker */
extern char heap_top; /* Defined by the linker */
char *prev_heap_end;
if (heap_end == 0)
{
heap_end = &heap_low;
}
prev_heap_end = heap_end;
if (heap_end + incr > &heap_top)
{
/* Heap and stack collision */
return (caddr_t)0;
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
链接器脚本
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000);
. = 0x8000;
.ro : {
*(.text.startup)
*(.text)
*(.rodata)
}
.rw : {
*(.data)
__bss_start__ = .;
*(.bss)
__bss_end__ = .;
*(COMMON)
}
. = ALIGN(8);
heap_low = .; /* for _sbrk */
. = . + 0x10000; /* 64kB of heap memory */
heap_top = .; /* for _sbrk */
. = . + 0x10000; /* 64kB of stack memory */
stack_top = .; /* for startup.s */
}
开始.s
.section ".text.startup"
.global _start
_start:
ldr sp, =stack_top
// The c-startup
b _cstartup
_inf_loop:
b _inf_loop
更新 2
涉及 snprintf 的进一步实验:
snprintf(s, 100, "hello world\r\n"); // Works
snprintf(s, 100, "hello %s\r\n", "world"); // Doesn't work
snprintf(s, 100, "hello %d\r\n", 1); // Doesn't work
char s[100];
char t[100];
strcpy(s, "hello world\r\n");
snprintf(t, 100, s); // Doesn't work