arm-none-eabi global initialized variable incorrect value












1














I try to make some example for stm32f334 (just led blink). I had a problem with the linker when I want to constrain using .data section (by use initialized global variable) I got a problem. Global variable got incorrect value!



This is my code:



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);
}


linker script:



    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


on the .list I see correct value and adress:



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


but when I debug code value of variable "wymuszenie_data" is corrupted (0x2e006816).



I really don't know why there is incorrect global variable value.



Best regards,
Marcin










share|improve this question




















  • 2




    I don't see anything in your startup code that copies the contents of the .data section to RAM.
    – Michael
    Nov 12 at 14:33
















1














I try to make some example for stm32f334 (just led blink). I had a problem with the linker when I want to constrain using .data section (by use initialized global variable) I got a problem. Global variable got incorrect value!



This is my code:



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);
}


linker script:



    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


on the .list I see correct value and adress:



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


but when I debug code value of variable "wymuszenie_data" is corrupted (0x2e006816).



I really don't know why there is incorrect global variable value.



Best regards,
Marcin










share|improve this question




















  • 2




    I don't see anything in your startup code that copies the contents of the .data section to RAM.
    – Michael
    Nov 12 at 14:33














1












1








1


1





I try to make some example for stm32f334 (just led blink). I had a problem with the linker when I want to constrain using .data section (by use initialized global variable) I got a problem. Global variable got incorrect value!



This is my code:



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);
}


linker script:



    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


on the .list I see correct value and adress:



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


but when I debug code value of variable "wymuszenie_data" is corrupted (0x2e006816).



I really don't know why there is incorrect global variable value.



Best regards,
Marcin










share|improve this question















I try to make some example for stm32f334 (just led blink). I had a problem with the linker when I want to constrain using .data section (by use initialized global variable) I got a problem. Global variable got incorrect value!



This is my code:



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);
}


linker script:



    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


on the .list I see correct value and adress:



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


but when I debug code value of variable "wymuszenie_data" is corrupted (0x2e006816).



I really don't know why there is incorrect global variable value.



Best regards,
Marcin







arm stm32 bare-metal linker-scripts gnu-arm






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 at 12:47









kaliczp

339713




339713










asked Nov 12 at 13:31









Lazor

112




112








  • 2




    I don't see anything in your startup code that copies the contents of the .data section to RAM.
    – Michael
    Nov 12 at 14:33














  • 2




    I don't see anything in your startup code that copies the contents of the .data section to RAM.
    – Michael
    Nov 12 at 14:33








2




2




I don't see anything in your startup code that copies the contents of the .data section to RAM.
– Michael
Nov 12 at 14:33




I don't see anything in your startup code that copies the contents of the .data section to RAM.
– Michael
Nov 12 at 14:33












1 Answer
1






active

oldest

votes


















6














This line



} > SRAM AT > flash


tells the linker that sections in the preceding block should be linked as if they were placed in RAM, but actually put to a different address in flash. The code looks for the data in RAM, but it's not there yet. You should arrange it to be copied before calling main(). As it is a bare metal embedded platform, there is no operating system loader to perform this task.



First, create a symbol with the destination address in the linker script.



__data_destination__ = LOADADDR(.data);


then copy (&__data_end__ - &__data_start__) bytes from &__data_start__ to &__data_destination__ before calling main().



You should as well clear .bss, i.e. fill it with zeroes to avoid the next surprise.



If you are linking with a C library, you can use memcpy() and memset(), otherwise you must write you own code in C or assembly.






share|improve this answer





















  • Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
    – Lazor
    Nov 13 at 20:58











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53263275%2farm-none-eabi-global-initialized-variable-incorrect-value%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









6














This line



} > SRAM AT > flash


tells the linker that sections in the preceding block should be linked as if they were placed in RAM, but actually put to a different address in flash. The code looks for the data in RAM, but it's not there yet. You should arrange it to be copied before calling main(). As it is a bare metal embedded platform, there is no operating system loader to perform this task.



First, create a symbol with the destination address in the linker script.



__data_destination__ = LOADADDR(.data);


then copy (&__data_end__ - &__data_start__) bytes from &__data_start__ to &__data_destination__ before calling main().



You should as well clear .bss, i.e. fill it with zeroes to avoid the next surprise.



If you are linking with a C library, you can use memcpy() and memset(), otherwise you must write you own code in C or assembly.






share|improve this answer





















  • Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
    – Lazor
    Nov 13 at 20:58
















6














This line



} > SRAM AT > flash


tells the linker that sections in the preceding block should be linked as if they were placed in RAM, but actually put to a different address in flash. The code looks for the data in RAM, but it's not there yet. You should arrange it to be copied before calling main(). As it is a bare metal embedded platform, there is no operating system loader to perform this task.



First, create a symbol with the destination address in the linker script.



__data_destination__ = LOADADDR(.data);


then copy (&__data_end__ - &__data_start__) bytes from &__data_start__ to &__data_destination__ before calling main().



You should as well clear .bss, i.e. fill it with zeroes to avoid the next surprise.



If you are linking with a C library, you can use memcpy() and memset(), otherwise you must write you own code in C or assembly.






share|improve this answer





















  • Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
    – Lazor
    Nov 13 at 20:58














6












6








6






This line



} > SRAM AT > flash


tells the linker that sections in the preceding block should be linked as if they were placed in RAM, but actually put to a different address in flash. The code looks for the data in RAM, but it's not there yet. You should arrange it to be copied before calling main(). As it is a bare metal embedded platform, there is no operating system loader to perform this task.



First, create a symbol with the destination address in the linker script.



__data_destination__ = LOADADDR(.data);


then copy (&__data_end__ - &__data_start__) bytes from &__data_start__ to &__data_destination__ before calling main().



You should as well clear .bss, i.e. fill it with zeroes to avoid the next surprise.



If you are linking with a C library, you can use memcpy() and memset(), otherwise you must write you own code in C or assembly.






share|improve this answer












This line



} > SRAM AT > flash


tells the linker that sections in the preceding block should be linked as if they were placed in RAM, but actually put to a different address in flash. The code looks for the data in RAM, but it's not there yet. You should arrange it to be copied before calling main(). As it is a bare metal embedded platform, there is no operating system loader to perform this task.



First, create a symbol with the destination address in the linker script.



__data_destination__ = LOADADDR(.data);


then copy (&__data_end__ - &__data_start__) bytes from &__data_start__ to &__data_destination__ before calling main().



You should as well clear .bss, i.e. fill it with zeroes to avoid the next surprise.



If you are linking with a C library, you can use memcpy() and memset(), otherwise you must write you own code in C or assembly.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 at 15:47









berendi

3,8911624




3,8911624












  • Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
    – Lazor
    Nov 13 at 20:58


















  • Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
    – Lazor
    Nov 13 at 20:58
















Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
– Lazor
Nov 13 at 20:58




Thanks, that was a problem. I have write codee that zeroes .bss and move .data from flash to ram and everything work well.
– Lazor
Nov 13 at 20:58


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53263275%2farm-none-eabi-global-initialized-variable-incorrect-value%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python