cancel
Showing results for 
Search instead for 
Did you mean: 

Stack memory location (STM32F205)

Valeev.Kamil
Associate II
Posted on December 23, 2015 at 08:57

Greetings forum,

I'm having a hard time understanding where is the stack located in the memory. In linker configuration file there's only one option you could change regarding stack -- it's stack size and it's default value is 0x2000. And there's also option to change the RAM starting address which is 0x20000000 by default. Hence one can assume that the stack is located in the region from 0x20000000 to 0x20002000, but in reality when I run the debugger, it shows that the current StackPointer (R13) value is 0x200035C0. So I assume that stack lies in region from 0x200015C0 to 0x200035C0. So I have the following questons in my mind:

1) What is located in the begining of the RAM? User Data?

2) What should I do in order to force stack to start from the beginning of the RAM?

Why do I even care about it? When using internal bootloader, you have to load Stack Pointer with the default value located in the first word of the SystemMemory (0x1fff0000). In STM32F205 the 0x20001000 value is located there, which does not belong to my stack interval (15C0-35C0). And when I'm using the debugger it warns me about it:

 ''The stack pointer for stack 'CSTACK' (currently 0x20000FD0) is outside the stack range (0x200015C0 to 0x200035C0)''.

However, bootloader is seems to work fine and I wonder what should I do in this situation: load stack pointer with the value 0x200035C0 or maybe something else.

I'm using STM32F205, IAR Embedded Workbench.

Thank you for your attention.

#stm32-stack-memory-location-boot
5 REPLIES 5
Valeev.Kamil
Associate II
Posted on December 23, 2015 at 11:40

Well, it seems that the beginning of RAM 0x20000000 -- 0x200015C0 contains all global variables. And stack region is dynamically changes whenever the new variable is added to the code. That doesn't make any sence for me. I thought that stack region is static and located in the beginning of the RAM (0x20000000 -- 0x20002000). Only after that variables should come occupying region 0x20002000 -- 0x200035C0. Am I wrong?

Valeev.Kamil
Associate II
Posted on December 23, 2015 at 12:58

OK, I figured it out. You can change CSTACK block location in the ILINK configuration file (with the extension .icf). The original file (stm32f205xE.icf) has this text:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x2000;
define symbol __ICFEDIT_size_heap__ = 0x2000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do
not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };

You have to make a copy of it and change the text of a new file to the following:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x2000;
define symbol __ICFEDIT_size_heap__ = 0x2000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do
not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };

place in RAM_region { readwrite, block HEAP };

place at address mem:__ICFEDIT_region_RAM_start__ {block CSTACK};

I highlighted the changed and added lines. As you can see, you have to place block CSTACK not somewhere on the RAM but

specifically

on the start of the RAM.
Posted on December 23, 2015 at 13:39

I'm not clear as to why the system loader is playing a role here, you have the BOOTx pins set correctly, or you are testing some other facet?

The stack is usually placed toward the end of memory and moves downward. GCC usually places it at the very end, while Keil and IAR typically place it beyond the statics and heap.

The debugger is just providing a warning, you'd probably want to understand why the loader SP is being loaded vs the one from your code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Valeev.Kamil
Associate II
Posted on December 23, 2015 at 14:00

I'm jumping to SystemMemory from the application without using BOOTx pins (as you have decribed it [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Jump%20to%20internal%20bootloader&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=6732]here ). You have to assign StackPointer with the value of memory cell 0x1FFF0000. I don't even know why.

What do you mean by saying 'end of memory'? RAM starts at the 0x20000000 and goes to the 0x2001FFFF. IAR places it near the start of the RAM, right after the static variables and maybe even after heap.

Posted on December 23, 2015 at 14:25

If you transfer control to the system loader, its a one way trip, and whatever you have in RAM could be destroyed. The SP is where the loader expects it to be, the debugger is just confused because you've moved outside the scope of where it has any context from the executable/object file.

On a 128K part you could place the initial SP at 0x20020000, it is decremented before the values are written.

At the end of the day the linker script or scatter files determine the placement, and the source files, often startup.s control the size, of the stack. The .MAP file should provide information about the placement of various structures.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..