This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Stack & Heap Initialization (RealView MDK-ARM)

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?

Parents
  • 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.

Reply
  • 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.

Children