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