0

在我的 cortex-m3 上,我试图将一个浮点变量输出到我的 UART 端口。所以我需要将其float DATA转换为char outputstr[].

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

  1. 如果我注释掉 sprintf(),我可以编译和链接。
  2. 如果我使用sprintf(outputstr, "t"),我可以编译和链接。
  3. 如果我使用sprintf(outputstr, "The value is %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路径和包含路径,如下所示:

另一方面,我也在使用libc.a 和 libgcc.a 中的和,这些函数可以编译、链接并正常工作strlen()other float division operations

    ...
    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 
    ...
  1. 有人可以建议吗?

  2. 另外,如果我遇到链接错误消息,例如:没有为可加载部分“.rodata”指定内存区域...我如何知道哪个对象的(.o).rodata 部分被排除在我的链接器脚本之外?


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

4

1 回答 1

0

为了解决链接错误('没有为可加载部分.bss等指定内存区域',我必须*(COMMON)在BSS输出部分中添加。

于 2014-08-18T02:37:04.230 回答