| |||

Home > Embedded Software Development > Further memory map considerations > Placing the stack and heap in the scatter-loading description file |

In many cases, it is preferable to specify the location of the stack and heap in the description file. This has two main advantages:

all information about the memory map is kept in one file

changes to the stack and heap only require relinking, not recompiling.

This section describes methods for implementing this:

*Stack pointer initialization* refers
to the symbols `stack_base`

and `heap_base`

as
reference symbols that can be placed in a description file. To do
this, create symbols labeled `stack_base`

and `heap_base`

in
an assembler module called `stackheap.s`

. The
same can be done for the stack and heap limits in a two-region memory
model.

You can locate each of the symbols within their own execution region in the description file, as shown in Example 2.15.

**Example 2.15. Placing symbols explicitly in stackheap.s**

AREA stacks, DATA, NOINIT EXPORT stack_base stack_base SPACE 1 AREA heap, DATA, NOINIT EXPORT heap_base heap_base SPACE 1 END

Figure 2.14 and Example 2.16 show how you can
place the heap base at `0x20000`

and the stack
base at `0x40000`

. The stack and heap base locations
can be altered by editing the addresses of the respective execution
regions.

The disadvantage of this approach is that one word of `SPACE`

(`stack_base`

)
is occupied above the stack region.

This method requires that the stack and heap sizes are specified in an object file.

First, define areas of an appropriate size for the stack and
heap in an assembler source file, for example, `stackheap.s`

,
as shown in Example 2.17.

Use the `SPACE`

directive to reserve a zeroed block
of memory. Set the `NOINIT`

area attribute to prevent
this zeroing.

During development, you might choose to zero-initialize the stack so that the maximum stack usage can be seen. Labels are not required in this source file.

**Example 2.17. Placing sections for stack and heap **

AREA stack, DATA, NOINIT SPACE 0x3000 ; Reserve stack space AREA heap, DATA, NOINIT SPACE 0x3000 ; Reserve heap space END

You can then place these sections in their own execution region in the scatter-loading description file, as shown in Example 2.18.

**Example 2.18. Placing sections for stack and heap**

LOAD_FLASH 0x24000000 0x04000000 { : STACKS 0x1000 UNINIT ; length = 0x3000 { stackheap.o (stack) ; stack = 0x4000 to 0x1000 } HEAP 0x15000 UNINIT ; length = 0x3000 { stackheap.o (heap) ; heap = 0x15000 to 0x18000 } }

The linker generates symbols that point to the base and limit
of each execution region, that can be imported into the retargeting
code to be used by `__user_initial_stackheap()`

:

Image$$STACKS$$ZI$$Limit = 0x4000

Image$$STACKS$$ZI$$Base = 0x1000

Image$$HEAP$$ZI$$Base = 0x15000

Image$$HEAP$$ZI$$Limit = 0x18000

You can make this code more readable by using the `DCD`

directive
to give these values more meaningful names, as shown in Example 2.19.

**Example 2.19. Using the DCD directive**

IMPORT ||Image$$STACKS$$ZI$$Base|| IMPORT ||Image$$STACKS$$ZI$$Limit|| IMPORT ||Image$$HEAP$$ZI$$Base|| IMPORT ||Image$$HEAP$$ZI$$Limit|| stack_base DCD ||Image$$STACKS$$ZI$$Limit|| ; = 0x4000 stack_limit DCD ||Image$$STACKS$$ZI$$Base|| ; = 0x1000 heap_base DCD ||Image$$HEAP$$ZI$$Base|| ; = 0x15000 heap_limit DCD ||Image$$HEAP$$ZI$$Limit|| ; = 0x18000

You can use these examples to place the heap base at `0x15000`

and
the stack base at `0x1000`

. You can then change
the stack and heap base locations easily by editing the addresses
of the respective execution regions.

This method uses the scatter file `EMPTY`

attribute
of the linker. This enables regions to be defined that contain no
object code or data. This is a convenient method of defining a stack
or heap. The length of the region is specified after the `EMPTY`

attribute. In
the case of a heap, that grows upwards in memory, the region length
is positive. In the case of a stack, the region length is marked
as negative, to indicate that it grows downwards in memory. Example 2.20 shows how
to use the `EMPTY`

attribute.

The benefit of this approach is that the size and position
of the stack and heap is defined in one place, that is, in the scatter-loading
description file. You do not have to create a `stackheap.s`

file.

**Example 2.20. Placing stack and heap regions using
EMPTY**

ROM_LOAD 0x24000000 0x04000000 { ... HEAP 0x30000 EMPTY 0x3000 { } STACKS 0x40000 EMPTY -0x3000 { } ... }

At link time, the linker generates symbols to represent these `EMPTY`

regions:

Image$$HEAP$$ZI$$Base = 0x30000

Image$$HEAP$$ZI$$Limit = 0x33000

Image$$STACKS$$ZI$$Base = 0x3D000

Image$$STACKS$$ZI$$Limit = 0x40000

Your application code can then process these symbols as shown in Example 2.21.

**Example 2.21. Linker generated symbols representing
EMPTY regions**

IMPORT ||Image$$HEAP$$ZI$$Base|| IMPORT ||Image$$HEAP$$ZI$$Limit|| heap_base DCD ||Image$$HEAP$$ZI$$Base|| heap_limit DCD ||Image$$HEAP$$ZI$$Limit|| IMPORT ||Image$$STACKS$$ZI$$Base|| IMPORT ||Image$$STACKS$$ZI$$Limit|| stack_base DCD ||Image$$STACKS$$ZI$$Limit|| stack_limit DCD ||Image$$STACKS$$ZI$$Base||