arm-none-eabi 全局初始化变量值不正确
Posted
技术标签:
【中文标题】arm-none-eabi 全局初始化变量值不正确【英文标题】:arm-none-eabi global initialized variable incorrect value 【发布时间】:2019-04-15 05:45:10 【问题描述】:我尝试为 stm32f334 做一些示例(只是 LED 闪烁)。当我想使用 .data 部分(通过使用初始化的全局变量)进行约束时,链接器出现问题,我遇到了问题。全局变量的值不正确!
这是我的代码:
startup.s
:
.global _start
.thumb_func
_start:
.word 0x20003000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
bl main
b hang
.thumb_func
hang: b .
blink.c
:
#define RCCBASE 0x40021000
#define GPIOBBASE 0x48000400
static int wymuszenie_bss;
int wymuszenie_data = GPIOBBASE;
int main ( void )
unsigned int* ptr;
wymuszenie_bss = 0x40021000;
ptr = (unsigned int*)(wymuszenie_bss+0x14);
*ptr |= 1<<18; //enable port B;
//moder
ptr = (unsigned int*)(wymuszenie_data+0x00);
*ptr &= ~(3<<24); //PB12
*ptr |= 1<<24; //PB12
//OTYPER
ptr = (unsigned int*)(wymuszenie_data+0x04);
*ptr &= ~(1<<6); //PB12
//ospeedr
ptr = (unsigned int*)(GPIOBBASE+0x08);
*ptr |= ~(3<<24); //PB12
//pupdr
ptr = (unsigned int*)(GPIOBBASE+0x0C);
*ptr &= ~(3<<24); //PB12
while(1)
ptr = (unsigned int*)(GPIOBBASE+0x18);
*ptr = (1<<12)<<0;
for(int ra=0;ra<400000;ra++) asm("NOP");;
ptr = (unsigned int*)(GPIOBBASE+0x18);
*ptr = (1<<12)<<16;
for(int ra=0;ra<400000;ra++) asm("NOP");;
return(0);
链接脚本:
MEMORY
flash : ORIGIN = 0x08000000, LENGTH = 0x1000
SRAM : ORIGIN = 0x20000000, LENGTH = 12K
SECTIONS
.text :
__text_start__ = .;
*(.text)
startup.o (.text);
blink.o (.text);
__text_end__ = .;
> flash
.data :
__data_start__ = .;
KEEP (*(.data))
KEEP (*(.data*))
__data_end__ = .;
> SRAM AT > flash
.bss :
__bss_start__ = .;
*(.bss)
__bss_end__ = .;
> SRAM
makefile
:
ARMGNU = arm-none-eabi
gcc : blink.bin
all : gcc
clean:
rm -f *.bin
rm -f *.o
rm -f *.elf
rm -f *.list
rm -f *.bc
rm -f *.opt.s
rm -f *.norm.s
rm -f *.nm
startup.o : startup.s
$(ARMGNU)-as --warn --fatal-warnings -mcpu=cortex-m4 startup.s -o startup.o
blink.o : blink.c
$(ARMGNU)-gcc -Wall -Wint-to-pointer-cast -g -c -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c blink.c -o blink.o
blink.bin : startup.o blink.o
$(ARMGNU)-ld -o blink.elf -T startup.ld startup.o blink.o
$(ARMGNU)-objdump -D blink.elf > blink.list
$(ARMGNU)-nm blink.elf > blink.nm
$(ARMGNU)-objcopy blink.elf blink.bin -O binary
在 .list 上我看到了正确的值和地址:
Disassembly of section .data:
20000000 <wymuszenie_data>:
20000000: 48000400 stmdami r0, sl
Disassembly of section .bss:
20000004 <__bss_start__>:
20000004: 00000000 andeq r0, r0, r0
但是当我调试变量“wymuszenie_data”的代码值时已损坏(0x2e006816)。
我真的不知道为什么全局变量值不正确。
最好的问候, 马辛
【问题讨论】:
我在您的启动代码中没有看到任何将.data
部分的内容复制到 RAM 的内容。
【参考方案1】:
这一行
> SRAM AT > flash
告诉链接器前面块中的部分应该被链接就像它们被放置在RAM中,但实际上被放置到闪存中的不同地址。该代码在 RAM 中查找数据,但它还没有。您应该在致电main()
之前将其复制。由于它是一个裸机嵌入式平台,因此没有操作系统加载程序来执行此任务。
首先,在链接描述文件中创建一个带有目标地址的符号。
__data_destination__ = LOADADDR(.data);
然后在调用main()
之前将(&__data_end__ - &__data_start__)
字节从&__data_start__
复制到&__data_destination__
。
您还应该清除.bss
,即用零填充它以避免下一个意外。
如果您要与 C 库链接,则可以使用 memcpy()
和 memset()
,否则您必须使用 C 或汇编编写自己的代码。
【讨论】:
谢谢,这是个问题。我编写了将 .bss 归零并将 .data 从闪存移动到 ram 的代码,一切正常。以上是关于arm-none-eabi 全局初始化变量值不正确的主要内容,如果未能解决你的问题,请参考以下文章