arm-none-eabi全局初始化变量值不正确
arm-none-eabi global initialized variable incorrect value
我尝试为 stm32f334 做一些例子(只是导致闪烁)。当我想限制使用 .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)。
我真的不知道为什么全局变量值不正确
此致,
马辛
这一行
} > SRAM AT > flash
告诉链接器前面块中的部分应该被链接 就好像 它们被放置在 RAM 中,但实际上被放置在闪存中的不同地址。代码在 RAM 中查找数据,但它还不存在。您应该安排在调用 main()
之前复制它。由于它是裸机嵌入式平台,因此没有操作系统加载程序来执行此任务。
首先,在链接描述文件中用目标地址创建一个符号。
__data_destination__ = LOADADDR(.data);
然后在调用 main()
.
之前将 (&__data_end__ - &__data_start__)
个字节从 &__data_start__
复制到 &__data_destination__
你也应该清除 .bss
,即用零填充它以避免下一个意外。
如果您正在链接 C 库,您可以使用 memcpy()
和 memset()
,否则您必须用 C 或汇编编写您自己的代码。
我尝试为 stm32f334 做一些例子(只是导致闪烁)。当我想限制使用 .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)。
我真的不知道为什么全局变量值不正确
此致, 马辛
这一行
} > SRAM AT > flash
告诉链接器前面块中的部分应该被链接 就好像 它们被放置在 RAM 中,但实际上被放置在闪存中的不同地址。代码在 RAM 中查找数据,但它还不存在。您应该安排在调用 main()
之前复制它。由于它是裸机嵌入式平台,因此没有操作系统加载程序来执行此任务。
首先,在链接描述文件中用目标地址创建一个符号。
__data_destination__ = LOADADDR(.data);
然后在调用 main()
.
(&__data_end__ - &__data_start__)
个字节从 &__data_start__
复制到 &__data_destination__
你也应该清除 .bss
,即用零填充它以避免下一个意外。
如果您正在链接 C 库,您可以使用 memcpy()
和 memset()
,否则您必须用 C 或汇编编写您自己的代码。