newlib中的printf在裸机ARM环境中不起作用

时间:2017-07-05 17:39:58

标签: c gcc arm bare-metal newlib

我正在一个裸机ARM项目中工作,我正在尝试集成newlib库。作为初学者,我试图让printf函数先工作,以便通过UART看到标准输出。我已经阅读了很多描述如何完成这项工作的在线文档。我没有盲目地遵循这些步骤,而是通过从这些文档中学习东西来完成所有工作。我在开始时犯了很多错误,但是一个接一个地修复它们并保持工作进展。        但根据我的互联网搜索,现在我已经遇到了一个迄今为止似乎没有人经历过的问题。现在让我谈谈实际问题。

printf函数返回时没有调用_write函数的实现。当我调试时,我可以看到printf正在调用我自己编写的其他系统调用(例如_isatty_sbrk_fstat)。

这些是我为解决链接问题而实现的系统调用(未定义的引用)

extern char __heap_start__;
extern char __heap_end__;

void _exit(int status)
{
    while (1);
}
void *_sbrk(int incr)
{
    static char *heap_end = &__heap_start__;
    char *base = heap_end;
    if(heap_end + incr > &__heap_end__)
    {
        errno = ENOMEM;
        return (void *)-1;
    }
    heap_end += incr;
    return base;
}
int _write(int fd, char *buff, int size)
{
    int i;
    for(i = 0; i < size; i++)
    {
        UART0_write_char(buff[i]);
    }
    return i;
}
int _read(int fd, char *buff, int size)
{
    return 0;
}

int _open(const char *name, int flags,int mode)
{
    return 0;
}

void _close(int fd)
{
}
int _isatty(int fd)
{
    return 1;
}
int _fstat(int fd, struct stat *st)
{
    st->st_mode = S_IFCHR;
    return 0;
}
off_t _lseek(int fd, off_t offset, int whence)
{
    return 0;
}

我的链接描述文件

STACK_HEAP_BOUNDARY_OFFSET = 0;
MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
    SRAM  (rw) : ORIGIN = 0x40000000, LENGTH = 32K
}

SECTIONS
{
    .text :
    {
        startup.o (.text)
        *(.text .txt.*)
        *(.glue_7)
        *(.glue_7t)
        . = ALIGN(4);
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    .ARM :
    {
        *(.ARM.exidx*)
    } >FLASH

    .rodata :
    {
        *(.rodata .rodata.*)
        . = ALIGN(4);
    } > FLASH

    .data :
    {
        __data_load__ = LOADADDR (.data);
        __data_start__ = .;
        *(.data .data.*)
        . = ALIGN(4);
        __data_end__ = .;
    } > SRAM AT > FLASH

    .bss :
    {
        __bss_start__ = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
    } > SRAM

    .heap :
    {
        __heap_start__ = .;
        PROVIDE(end = __heap_start__);
        PROVIDE(_heap_start = __heap_start__);
        . = . + ((LENGTH(SRAM) - (. - (ORIGIN(SRAM)))) / 2);
        . += STACK_HEAP_BOUNDARY_OFFSET;
        . = ALIGN(4);
        __heap_end__ = .;
        PROVIDE(_heap_end = __heap_end__);
    } > SRAM

    .stack :
    {
        __stack_start__ = .;
        . = . + (LENGTH(SRAM) - (. - (ORIGIN(SRAM))));
        . = ALIGN(4);
        __stack_end__ = .;
        __stack_size__ = __stack_end__ - __stack_start__;
        __IRQ_stack_top__ = (__stack_start__ + (__stack_size__ / 2));
    } > SRAM
}

我的Makefile

TOOLCHAIN_PREFIX:=arm-none-eabi-
CC := $(TOOLCHAIN_PREFIX)gcc
LD := $(TOOLCHAIN_PREFIX)ld
AS := $(TOOLCHAIN_PREFIX)as
AR := $(TOOLCHAIN_PREFIX)ar -cr
OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy

RM := rm -f

TARGET := image.hex

OBJS := startup.o $(patsubst %.c,%.o,$(wildcard *.c))

CFLAGS := -mcpu=arm7tdmi-s -g3 -Wall -I. -gdwarf-2
AS_FLAGS := -mcpu=arm7tdmi-s -g3 -gdwarf-2

LD_FLAGS := -Wl,-Map,$(TARGET:%.hex=%).map -nostartfiles

LD_SCRIPT := lpc2138.ld

all :   $(TARGET)

$(TARGET) : $(TARGET:%.hex=%.elf)
    $(OBJCOPY) -O ihex $< $@

$(TARGET:%.hex=%.elf) : $(OBJS)
    $(CC) -o $@ -T $(LD_SCRIPT) $(OBJS) $(LD_FLAGS)

startup.o : startup.s
    $(AS) $(AS_FLAGS) -o $@ $<

%.o : %.c
    $(CC) -c $(CFLAGS) -o $@ $<

clean :
    $(RM) $(TARGET) $(TARGET:%.hex=%.elf) $(TARGET:%.hex=%).map *.o

如果我方需要进一步的信息,请告诉我。提前谢谢

编辑:

启动代码

/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
Mode_USR    =   0x10
Mode_FIQ    =   0x11
Mode_IRQ    =   0x12
Mode_SVC    =   0x13
Mode_ABT    =   0x17
Mode_UND    =   0x1B
Mode_SYS    =   0x1F

I_Bit       =   0x80    /* when I bit is set, IRQ is disabled */
F_Bit       =   0x40    /* when F bit is set, FIQ is disabled */

    .text
    .arm
    .global _start
    .func   _start
_start:
    B   _reset              /* Reset vector */
    B   _loop               /* Undefined Instruction */
    B   _loop               /* Software Interrupt */
    B   _loop               /* Prefetch Abort */
    B   _loop               /* Data Abort */
    NOP                     /* Reserved */
    LDR pc, [pc, #-0x0FF0]  /* VicVectAddr */
    /* LDR pc, _fiq_addr */
    B   _loop               /* FIQ Handler */
_reset:
/* Enable FIQ and IRQ */
    MSR CPSR_c,#(Mode_IRQ | I_Bit | F_Bit)
    LDR SP, =__IRQ_stack_top__
    MSR CPSR_c,#Mode_SVC

/* Relocate the .data section (copy from ROM to RAM) */
    LDR r0,=__data_load__
    LDR r1,=__data_start__
    LDR r2,=__data_end__
_l1:
    CMP r1,r2
    LDMLTIA r0!,{r3}
    STMLTIA r1!,{r3}
    BLT _l1

    /* Clear the .bss section (zero init) */
    LDR r1,=__bss_start__
    LDR r2,=__bss_end__
    MOV r3,#0
_l2:
    CMP r1,r2
    STMLTIA r1!,{r3}
    BLT _l2

    LDR sp,=__stack_end__
    LDR FP,=__stack_end__
    LDR r0,=main
    MOV lr,pc
    BX  r0
_loop:
    B   _loop

/* _fiq_addr:
    .word VIC_FIQ_handler
*/
    .endfunc
    .end

0 个答案:

没有答案