Target hardware and the memory map

The previous sections describe the placement of code and data in a scatter-loading description file. However, the location of target hardware peripherals and the stack and heap limits are assumed to be hard-coded in source or header files. It is better to locate all information about the memory map of a target in your description file, and remove all references to absolute addresses from your source code.

Conventionally, addresses of peripheral registers are hard-coded in project source or header files. You can also declare structures that map on to peripheral registers, and place these structures in the scatter-loading description file.

For example, if a target has a timer peripheral with two memory mapped 32-bit registers, a C structure that maps to these registers is:

Example 8. Mapping to a peripheral register

__attribute__ ((zero_init)) struct
{
    volatile unsigned ctrl;           /* timer control */
    volatile unsigned tmr;            /* timer value   */
} timer_regs;

To place this structure at a specific address in the memory map, you can create an execution region containing the module that defines the structure. The following example shows an execution region called TIMER that locates the timer_regs structure at 0x40000000:

Example 9. Placing the mapped structure

ROM_LOAD 0x24000000 0x04000000
{
; ...
TIMER 0x40000000 UNINIT
    {
        timer_regs.o (+ZI)
    }
    ; ...
}

It is important that the contents of these registers are not zero initialized during application startup, because this is likely to change the state of your system. Marking an execution region with the UNINIT attribute prevents ZI data in that region from being zero initialized by __main.

Copyright © 2010-2012 ARM. All rights reserved.ARM DUI 0471G
Non-ConfidentialID021412