3

我正在尝试集成 newlib 库的裸机 ARM 项目。作为初学者,我试图让该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
4

0 回答 0