We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
There are some codes in the "Startup.s" for "User Initial Stack & Heap".
And, as per this URL http://www.keil.com/support/man/docs/armlib/armlib_chdegjfd.htm
There are another codes for "Sets up the heap and stack".
It makes me a little confused.
What is the relationship between these two "Stack & Heap Initialization"?
Are they duplicated works, or they have different and important meanings?
If we ignore the other things (such like Memery Areas for Interrupt Vector Table, Hardware Addresses Remapping) then, can I say that, there are only 4 parts in the RAM Area: 1. Stack 2. Heap 3. ZI Area 4. RW Area But I still got confused, does the Library has its own ZI, RW, which are not located between 0x-4000-1000 and 0x-4000-0100?
Maybe the Runtime Memory Map should look like the below?
----RAM-------------- 0x-6FFF-FFFF ------------------------ | ZI AREA for Prg4/Lib4 ------------------------ | RW AREA for Prg4/Lib4 ------------------------ | ZI AREA for Prg3/Lib3 ------------------------ | RW AREA for Prg3/Lib3 ------------------------ | Stack-ASM-start (Defined in the "Startup.s") | | ------------------ | Stack-Prg1/Lib1-start (__rt_entry done for me) | | Stack-Prg1/Lib1-end (__rt_entry done for me) | ------------------ | Stack-Prg2/Lib2-start (__rt_entry done for me) | | Stack-Prg2/Lib2-end (__rt_entry done for me) | ------------------ | Stack-Prg3/Lib3-start (__rt_entry done for me) | | Stack-Prg3/Lib3-end (__rt_entry done for me) | ------------------ | Stack-Prg4/Lib4-start (__rt_entry done for me) | | Stack-Prg4/Lib4-end (__rt_entry done for me) | ------------------ | | Stack-ASM-end (Defined in the "Startup.s") --------------------- | Heap-ASM-end (Defined in the "Startup.s") | | ------------------ | Heap-Prg1/Lib1-start (__rt_entry done for me) | | Heap-Prg1/Lib1-end (__rt_entry done for me) | ------------------ | Heap-Prg2/Lib2-start (__rt_entry done for me) | | Heap-Prg2/Lib2-end (__rt_entry done for me) | ------------------ | Heap-Prg3/Lib3-start (__rt_entry done for me) | | Heap-Prg3/Lib3-end (__rt_entry done for me) | ------------------ | Heap-Prg4/Lib4-start (__rt_entry done for me) | | Heap-Prg4/Lib4-end (__rt_entry done for me) | ------------------ | | Heap-ASM-start (Defined in the "Startup.s") ------------------------ | ZI AREA for Prg2/Lib2 ------------------------ | RW AREA for Prg2/Lib2 ------------------------ | ZI AREA for Prg1/Lib1 ------------------------ | RW AREA for Prg1/Lib1 ----RAM----------------- ------------------- --------------------- | Flash | ---------------------
Sorry for that I am not able to express my questions precisely and clearly. (even in my first language)
Does the below statements correct?
Who will need a Heap Area? the application which needs to dynamically allocate memory during runtime.
Who will need a Stack Area? 1. CPU mode switching, each mode has its own Stack Pointer, but we have only one RAM Area. 2. When an Interrupt Service Routines is triggered, such like UART-Handler, Timer-Handler. 3. An application calls a function (Call and Return).
The Stack/Heap defined in the Startup.s are continuous memery area.
All the stacks/heaps which are needed by Hardware (CPU Mode Switching), Interrupt Service Routines (HW/SW ISR), Applications (My C programs, the Libraries) must be put into "the Stack/Heap defined in the Startup.s".
Does the below Runtime Memory Map correct?
----RAM-------------- 0x-6FFF-FFFF | Stack-ASM-start (Defined in the "Startup.s") | ------------------ | Stack-CPU mode switching-start | (Defined in the "Startup.s") | Stack-CPU mode switching-end | ------------------ | Stack-Interrupt Service Routines-start | (Where is the code, which defined this?) | Stack-Interrupt Service Routines-end | ------------------ | Stack-MyCprg-start (__rt_entry done for me) | | Stack-MyCprg-end (__rt_entry done for me) | ------------------ | Stack-Lib01-start (__rt_entry done for me) | | Stack-Lib01-end (__rt_entry done for me) | ------------------ | Stack-Lib02-start (__rt_entry done for me) | | Stack-Lib02-end (__rt_entry done for me) | ------------------ | | Stack-ASM-end (Defined in the "Startup.s") --------------------- | Heap-ASM-end (Defined in the "Startup.s") | ------------------ | Interrupt Service Routines do not need HEAP? | ------------------ | Heap-MyCprg-start (__rt_entry done for me) | | Heap-MyCprg-end (__rt_entry done for me) | ------------------ | Heap-Lib01-start (__rt_entry done for me) | | Heap-Lib01-end (__rt_entry done for me) | ------------------ | Heap-Lib02-start (__rt_entry done for me) | | Heap-Lib02-end (__rt_entry done for me) | ------------------ | Heap-ASM-start (Defined in the "Startup.s") --------------------- 0x-4000-1000
You have one heap area, that may be zero size large if you do not need any dynamic memory allocations.
Both your program and some CRTL functions may need the heap. You define the size of this heap in the startup file. The startup file then calls an initialization function for the CRTL and if any heap space has been declared, then the RTL init function will initialize a couple of internal structures to prepare the heap to be used.
For some processor architectures, you have a single stack. The ARM has separate stacks for the different interrupt handlers. So you define the sizes of these stacks in the startup file. The C runtime library do not have its own stack. There is one stack that the user application will use. When you make calls to the RTL, then this is your application, so the RTL will use the same stack.
If running with a RTOS, then you may use dynamic memory or global variables (ZI space) to declare more stacks and initialize the RTOS threads to use these extra stacks. But the startup file will not know about them. It will only know about that initial stack it has set up for use before your main() function gets called. So in an RTOS environment, you may have the startup file create a very small stack, and then let main directly create a couple of threads with new stacks. In short, you may need an small initial stack for a very short while just while kick-starting the RTOS.
Your chip can have more than one RAM region (or you may have internal RAM and external RAM). But you normally link your program to have only one ZI region and one RW region, even if the linker may decide to split one of these regions into two and place some variables in one sub-block and some variables in another sub-block. But that is just a linker optimization to make best use of multiple RAM memories. The startup code obviously have to be quite smart to support this, since initialization of RW memory may have to span non-contiguous memory. In the same way, the zero-initialization of the ZI memory may also have to be split. When you browse the map file (if turned on) you will notice that each object file will show a summary about RW and ZI space needed, but in the end the ZI regions from all object files will be placed side-by-side, and all RW variables from the different object files will be placed side-by-side.
If you have special needs, then you can define special memory regions where you place variables. You might for example want uninitialized variables that are not ZI-initialized since you may have a region that has battery backup. If this region is used for RW or ZI then the variables will be overwritten on every boot.
So in the end: - no, the RTL does not have its own stack. The used stack is for the current mode of the processor, i.e. IRQ, FIQ, user, ... and not for application contra RTL. - no, the RTL does not have its own heap. The RTL can support a single pool of memory (the heap) and any call for dynamic allocations will eat from this heap. But you (or an RTOS) may define other memory allocation schemes. But they will normally also take memory from a pool because of the function name you call, and not controlled by which source line that made the call.
Hi Per,
Many Thanks to your explanations.
Though I need some time to completely understand these concepts, but I think I've already got some key points.