You copied the Doc URL to your clipboard.

Stack pointer initialization and heap bounds

The C library requires you to specify where the stack pointer begins. If you intend to use ARM library functions that use the heap, for example, malloc(), calloc(), or if you define argc and argv command-line arguments for main(), the C library also requires you to specify which region of memory the heap is initially expected to use.

The region of memory used by the heap can be extended at a later stage of program execution, if required.

You can specify where the stack pointer begins, and which region of memory the heap is initially expected to use, with any of the following methods:

  • Define the symbol __initial_sp to point to the top of the stack. If using the heap, also define symbols __heap_base and __heap_limit.

  • In a scatter file, either:

    • Define ARM_LIB_STACK and ARM_LIB_HEAP regions.

    • If you do not intend to use the heap, only define an ARM_LIB_STACK region.

    • Define an ARM_LIB_STACKHEAP region.

    If you define an ARM_LIB_STACKHEAP region, the stack starts at the top of that region. The heap starts at the bottom.

    Note

    These are the only methods that microlib supports for defining where the stack pointer starts and for defining the heap bounds.

  • Implement __user_setup_stackheap() to set up the stack pointer and return the bounds of the initial heap region.

  • If you are using legacy code that uses __user_initial_stackheap(), and you do not want to replace __user_initial_stackheap() with __user_setup_stackheap(), continue to use __user_initial_stackheap().

    Note

    ARM recommends that you switch to using __user_setup_stackheap() if you are still using __user_initial_stackheap(), unless your implementation of __user_initial_stackheap() is:

    • Specialized in some way so that it is complex enough to require its own temporary stack to run on before it has created the proper stack.

    • Has some user-specific special requirement that means it has to be implemented in C rather than in assembly language.

The initial stack pointer must be aligned to a multiple of eight bytes.

By default, if memory allocated for the heap is destined to overlap with memory that lies in close proximity with the stack, the potential collision of heap and stack is automatically detected and the requested heap allocation fails. If you do not require this automatic collision detection, you can save a small amount of code size by disabling it with asm(" .global __use_two_region_memory\n");.

Note

The memory allocation functions (malloc(), realloc(), calloc(), posix_memalign()) attempt to detect allocations that collide with the current stack pointer. Such detection cannot be guaranteed to always be successful.

Although it is possible to automatically detect expansion of the heap into the stack, it is not possible to automatically detect expansion of the stack into heap memory.

For legacy purposes, it is possible for you to bypass all of these methods and behavior. You can do this by defining the following functions to perform your own stack and heap memory management:

  • __rt_stackheap_init().

  • __rt_heap_extend().

Was this page helpful? Yes No