在我的 cortex-m3 上,我试图将一个浮点变量输出到我的 UART 端口。所以我需要将其float DATA
转换为char outputstr[]
.
为此,我使用了 libc.a 中的 sprintf
- 如果我注释掉 sprintf(),我可以编译和链接。
- 如果我使用
sprintf(outputstr, "t")
,我可以编译和链接。 - 如果我使用
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
...
有人可以建议吗?
另外,如果我遇到链接错误消息,例如:没有为可加载部分“.rodata”指定内存区域...我如何知道哪个对象的(.o).rodata 部分被排除在我的链接器脚本之外?
更新:我意识到如果在 main() 中调用了 sprintf() 函数,程序可以编译和链接成功.. 但是如果我在其他函数中调用 sprintf() 函数,我会得到上面的链接错误(没有内存区域指定为可加载部分 .bss),即使我使用 *(.bss) 作为输出部分的输入部分。