Boards supported by CS3 can have multiple banks or regions of memory with different characteristics. This section describes how program sections are mapped onto memory regions, and how you can use these CS3 features to customize placement of your program's code or data in memory. CS3 also provides a uniform set of symbolic names for each region, allowing you to programmatically refer to each region's address range from C or assembly language as well as from the linker script.
The regions that are available on a particular board are listed in the table for that board in Section 5.5, “Supported Boards for ARM EABI”, below. There are two kinds of regions: those documented as "Memory regions", which are general-purpose memory banks that can be used for program or data storage; and those documented as "Other regions", which typically correspond to memory-mapped control registers or other special-purpose storage.
CS3 supports boards that include both ram
and rom
memory regions. The ram
region holds the .data
and .bss
sections, and the .text
section in RAM profiles.
In ROM profiles, the rom
region holds the
.text
section and initialization values for
the writable data sections.
In addition, all regions documented as "Memory regions" correspond to
similarly-named program sections.
For example, the linker script assigns the .ram
section to the ram
region.
More generally, for a memory region named
R
, CS3 linker scripts define a
section named .
,
which may contain initialized data or code. There is also a section
named R
.bss.
for
zero-initialized data (BSS), which is placed after the initialized
data section for this region.
R
You can explicitly locate data or code in a section
corresponding to a particular memory region using
section attributes in your source C or C++ code.
Section attributes are especially useful on code compiled for
boards that include special memory banks, such as a fast on-chip
cache memory, in addition to the default
ram
and/or rom
regions.
CS3's start-up code arranges for additional data-like sections
to be initialized in the same way as the default
.data
section.
As an example to illustrate the attribute syntax,
you can put a variable
v
in the .ram
section using:
int v __attribute__ ((section (".ram")));
To declare a function f
in this section, use:
int f (void) __attribute__ ((section (".ram"))) {...}
For more information about attribute syntax, see the GCC manual.
In addition to the .
and R
.bss.
sections,
CS3 places a
R
.cs3.region-head.
section at the beginning of each region R
R
.
Explicitly placing data in
.cs3.region-head.
sections is discouraged, because CS3 itself may want to place items
(like interrupt vector tables) at these locations.
If there is a conflict, CS3 raises an error at link time.
R
Regions documented as "Other regions" in the tables in
Section 5.5, “Supported Boards for ARM EABI”
do not have corresponding program sections.
Typically, these regions contain
memory-mapped control and I/O registers and cannot be used for
general data or program storage.
If your program needs to manipulate data in
these regions, you can use the CS3 memory map access interface
declared in cs3.h
,
as described in Section 5.3.2, “Programmatic Access to the CS3 Memory Map”.
Memory maps for boards supported by Sourcery CodeBench Lite for ARM EABI
are documented in
XML files in the arm-none-eabi/lib/boards/
subdirectory of your Sourcery CodeBench installation directory.
CS3 makes C declarations describing the memory regions on the
target board available to your program via the header file
cs3.h
, which you can
find in the
arm-none-eabi/include
directory
within your install.
For each region named R
,
cs3.h
declares a byte array
variable
__cs3_region_start_
at the region's start address, and a R
size_t
variable
__cs3_region_size_
to represent the total size of the region. These symbols are
defined by the linker script and so may also be referenced from
assembly language. Note that all regions are aligned on eight-byte
boundaries and sizes are also multiples of eight bytes.
R
For memory regions that can correspond to program
sections (as described in Section 5.3.1, “Memory Regions and Program Sections”),
there are additional symbols
__cs3_region_init_
and
R
__cs3_region_init_size_
that describe constant data used to initialize the region.
During the C initialization phase (Section 5.2, “Program Startup and Termination”),
this data is copied into the lower part of the memory region.
The symbol
R
__cs3_region_zero_size_
represents the size of the zero-initialized
R
.bss.
section
following the initialized data.
Any of these identifiers may actually be defined as a preprocessor
macro that expands to an expression of the appropriate type and
value.
R
To perform the memory region initializations during startup,
CS3 internally uses the array variable
__cs3_regions
, which
contains descriptors for all of the writable (RAM) memory regions.
These descriptors are also exposed in
cs3.h
;
refer to the header file for details.
CS3 linker scripts provide default placement of the heap and stack in the RAM region. However, you can override the defaults by providing your own definitions of the associated CS3 variables. For example, you may put the heap and/or stack in some other memory region.
Heap placement is controlled by defining the symbol
__cs3_heap_start
at the beginning of the heap,
and either the symbol __cs3_heap_end
or the
pointer variable __cs3_heap_limit
to mark the
end of the heap. For example, this fragment of C code places
the heap in a region named extsram
:
#define HEAPSIZE ... /* However big you want to make it. */ unsigned char __cs3_heap_start[HEAPSIZE] __attribute__ ((section (".bss.extsram"), aligned(8))); unsigned char *__cs3_heap_limit = __cs3_heap_start + HEAPSIZE;
The default initial stack pointer for bare-metal profiles
is given by the symbol __cs3_stack
, and the stack
grows downward from this address.
Stack initialization is discussed in more detail in
Section 5.2.2, “The Assembly Initialization Phase”.
You can find C declarations for the CS3 heap and stack symbols
in the header file cs3.h
.
The cs3.h
header file also
defines a macro for creating a custom stack. The custom stack is
created as a block of RAM in the zero-initialized data section (BSS).
The specified size must be a compile-time constant. To account for
alignment, the final size of the stack may be a few bytes less than the
requested size. The symbol __cs3_stack
is
initialized to point to the last extent of the stack block, and is
16-byte aligned.
For example, the following fragment of C code creates a stack of 8192
bytes:
#include <cs3.h> CS3_STACK(2 * 4096);
As indicated in Section 5.2.2, “The Assembly Initialization Phase”, there are cases where a boot monitor or simulator overrides a custom stack.