Linker 使用sprintf()时发生链接错误

Linker 使用sprintf()时发生链接错误,linker,printf,linker-scripts,Linker,Printf,Linker Scripts,在cortex-m3上,我试图向UART端口输出一个浮点变量。。所以我需要将浮点数据转换为char outputstr[] 为此,我使用了libc.a中的sprintf 如果我注释掉sprintf,我可以编译和链接。 如果我使用sprintfoutputstr,t,我可以编译和链接。 如果我使用sprintfoutputstr,值是%f,DATA,我将得到链接错误,例如:没有为可加载节“.rodata”、“.bss”、“.text”、“.DATA”指定内存区域 但我已经添加了*.rodata、*

在cortex-m3上,我试图向UART端口输出一个浮点变量。。所以我需要将浮点数据转换为char outputstr[]

为此,我使用了libc.a中的sprintf

如果我注释掉sprintf,我可以编译和链接。 如果我使用sprintfoutputstr,t,我可以编译和链接。 如果我使用sprintfoutputstr,值是%f,DATA,我将得到链接错误,例如:没有为可加载节“.rodata”、“.bss”、“.text”、“.DATA”指定内存区域 但我已经添加了*.rodata、*.bss等。。。在我的链接器脚本中,如下所示:

...
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(reset_handler)

MEMORY {
   ROM : ORIGIN = 0x08000000, LENGTH = 128K
   RAM : ORIGIN = 0x20000000, LENGTH = 16K
}

SECTIONS {

    .ROMdata 0x8000000: AT(0x8000000){
    startup.o(.romvect)
    . = ALIGN(0x4);
    system_stm32l1xx.o(.rodata*)
    *(.rodata*)
    _ROMdataend_ = ALIGN(0x4);
    }

    .ROMstartup (_ROMdataend_): AT(_ROMdataend_){
    startup.o(.startup)
    lowlevelinit.o(.lowlevelinit .tempexchandler)
    system_stm32l1xx.o(.text*)
    . = ALIGN(0x4);
    }

    .RAMbss 0x20000000 (NOLOAD):{

    lowlevelinit.o(.ramvectortable)
    . = ALIGN(0x4);
    _RAMbssstart_ = .;
    startup.o(.stack .heap)
    . = ALIGN(0x4);
    sensor_MTH01.o(.bss*)
    . = ALIGN(0x4);
    comm_BT-HC-05.o(.bss)
    tim6.o(.bss)
    main.o(.bss)
    system_stm32l1xx.o(.bss*)
    *(.bss*)
    _RAMbssend_ = ALIGN(0x4);
    }

    .RAMcode (_RAMbssend_): AT(LOADADDR(.ROMstartup)+SIZEOF(.ROMstartup)){
    _RAMcodeVMAstart_ = .;
    _RAMcodeLMAstart_ = LOADADDR(.RAMcode);
    main.o(.ramcode .text)
    tim6.o(.tim6isr)
    tim6.o(.text)
    sensor_MTH01.o(.text)
    comm_BT-HC-05.o(.text)
    exti0_isr.o(.exti0isr)
    *(.text*)
    KEEP (*(.eh_*))
    _RAMcodeVMAend_ = ALIGN(0x4);
    }

    .RAMdata (_RAMcodeVMAend_): AT(LOADADDR(.RAMcode)+SIZEOF(.RAMcode)){
    _RAMcodeLMAend_ = (LOADADDR(.RAMcode)+SIZEOF(.RAMcode));
    _RAMdataVMAstart_ = .;
    _RAMdataLMAstart_ = LOADADDR(.RAMdata);
    sensor_MTH01.o(.data)
    system_stm32l1xx.o(.data*)
    *(.data*)
    _RAMdataVMAend_ = ALIGN(0x4);
    _RAMdataLMAend_ = LOADADDR(.RAMdata) + SIZEOF(.RAMdata);
    }


}
...
此外,我确实在makefile中包含了lib路径和include路径,如下所示:

...
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(reset_handler)

MEMORY {
   ROM : ORIGIN = 0x08000000, LENGTH = 128K
   RAM : ORIGIN = 0x20000000, LENGTH = 16K
}

SECTIONS {

    .ROMdata 0x8000000: AT(0x8000000){
    startup.o(.romvect)
    . = ALIGN(0x4);
    system_stm32l1xx.o(.rodata*)
    *(.rodata*)
    _ROMdataend_ = ALIGN(0x4);
    }

    .ROMstartup (_ROMdataend_): AT(_ROMdataend_){
    startup.o(.startup)
    lowlevelinit.o(.lowlevelinit .tempexchandler)
    system_stm32l1xx.o(.text*)
    . = ALIGN(0x4);
    }

    .RAMbss 0x20000000 (NOLOAD):{

    lowlevelinit.o(.ramvectortable)
    . = ALIGN(0x4);
    _RAMbssstart_ = .;
    startup.o(.stack .heap)
    . = ALIGN(0x4);
    sensor_MTH01.o(.bss*)
    . = ALIGN(0x4);
    comm_BT-HC-05.o(.bss)
    tim6.o(.bss)
    main.o(.bss)
    system_stm32l1xx.o(.bss*)
    *(.bss*)
    _RAMbssend_ = ALIGN(0x4);
    }

    .RAMcode (_RAMbssend_): AT(LOADADDR(.ROMstartup)+SIZEOF(.ROMstartup)){
    _RAMcodeVMAstart_ = .;
    _RAMcodeLMAstart_ = LOADADDR(.RAMcode);
    main.o(.ramcode .text)
    tim6.o(.tim6isr)
    tim6.o(.text)
    sensor_MTH01.o(.text)
    comm_BT-HC-05.o(.text)
    exti0_isr.o(.exti0isr)
    *(.text*)
    KEEP (*(.eh_*))
    _RAMcodeVMAend_ = ALIGN(0x4);
    }

    .RAMdata (_RAMcodeVMAend_): AT(LOADADDR(.RAMcode)+SIZEOF(.RAMcode)){
    _RAMcodeLMAend_ = (LOADADDR(.RAMcode)+SIZEOF(.RAMcode));
    _RAMdataVMAstart_ = .;
    _RAMdataLMAstart_ = LOADADDR(.RAMdata);
    sensor_MTH01.o(.data)
    system_stm32l1xx.o(.data*)
    *(.data*)
    _RAMdataVMAend_ = ALIGN(0x4);
    _RAMdataLMAend_ = LOADADDR(.RAMdata) + SIZEOF(.RAMdata);
    }


}
...
另一方面,我还使用了strlen和libc.a和libgcc.a中的其他浮点除法操作,以及这些函数complile、link和workok

    ...
    CC = arm-none-eabi-gcc
    AS = arm-none-eabi-as
    LD = arm-none-eabi-ld
    OBJCPY = arm-none-eabi-objcopy

    CCFLAGS = -c -mcpu=cortex-m3 -mthumb -O0 -g -Wall
    ASMFLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2
    LDFLAGS = -T CortexM3.ld -M=memmap.map
    OBJCPYFLAGS = -O ihex
    FLOATFLAGS = -mfloat-abi=soft -mfpu=vfp
    LIBDIR = -L C:\\yagarto-20121222\\lib\\gcc\\arm-none-eabi\\4.7.2\\thumb\\v7m -L C:\\yagarto-20121222\\arm-none-eabi\\lib\\thumb\\v7m
    INCDIR = -I C:\\yagarto-20121222\\lib\\gcc\\arm-none-eabi\\4.7.2\\include -I C:\\yagarto-20121222\\arm-none-eabi\\include

    all: m3.elf
    m3.elf: startup.o lowlevelinit.o system_stm32l1xx.o main.o tim6.o exti0_isr.o sensor_MTH01.o comm_BT-HC-05.o
        $(LD) $(LDFLAGS) $(LIBDIR) $^ -lc -lgcc -o $@
        $(OBJCPY) $(OBJCPYFLAGS) m3.elf m3.hex
    startup.o: startup.s
    lowlevelinit.o: lowlevelinit.c system_stm32l1xx.h stm32l1xx.h core_cm3.h
    system_stm32l1xx.o: system_stm32l1xx.c stm32l1xx.h core_cm3.h system_stm32l1xx.h
    main.o: main.c stm32l1xx.h
    tim6.o: tim6.c
    exti0_isr.o: exti0_isr.c
    sensor_MTH01.o: sensor_MTH01.c
    comm_BT-HC-05.o: comm_BT-HC-05.c

    clean:
        -rm -f startup.o lowlevelinit.o system_stm32l1xx.o main.o tim6.o tim6_isr.o exti0_isr.o sensor_MTH01.o comm_BT-HC-05.o memmap.map m3.elf m3.hex

    %.o: %.s
        $(AS) $(ASMFLAGS) $< -o $@
    %.o: %.c
        $(CC) $(CCFLAGS) $(INCDIR) $(FLOATFLAGS) $< -o $@


    .PHONY: all clean 
    ...
有人能提供建议吗

此外,如果我遇到链接错误消息,如:没有为可加载节“.rodata”指定内存区域。。。如何知道链接器脚本中遗漏了哪个对象的.o.rodata节

更新:
我意识到如果在main中调用sprintf函数,程序可以成功编译和链接。。但是,如果我在其他函数中调用sprintf函数,我将得到上面的链接错误:没有为可加载节.bss指定内存区域,即使我使用*.bss作为输出节的输入节。

要解决链接错误“没有为可加载节.bss等指定内存区域”,我必须在BSS输出部分添加*COMMON