Memory Layout#
Memory layout of a C/C++ project is controlled by the linker in your toolchain. Memory layout in this documentation means the location of functions and data in flash memory and RAM on a Silicon Labs EFR32/EFM32. When using GCC, the GNU Linker is using GNU linker scripts (.ld) to control the memory layout and when using IAR Embedded Workbench IAR ILINK is using linker configuration files (.icf) to control the memory layout of the application.
Simplicity SDK provides the Simplicity Studio Project Configurator which, can be used to generate these toolchain-dependent linker files. These linker files will be created based on the project description, target device, and components used in a project. Using the generated linker files, the sections of the applications will be placed in a deterministic way, which will allow the application to be used with Silicon Labs devices.
Toolchains#
GCC and IAR are the supported toolchains. The GCC generated linker script,
linkerfile.ld
is placed in the autogen
folder. The IAR-generated linker
configuration file, linkerfile.icf
is also placed in the autogen
folder. The
generated project files will refer to these files.
Note that the linker files are auto generated based on the components included in the project and will be overwritten whenever the application is re-generated.
Graphical View of Standard Memory Layout#
This is a graphical view of a typical memory layout of an application built using the Silicon Labs Simplicity SDK. This shows the relative placement of various sections. Note that some of the sections in the image are optional and do not have to be present in all applications.
Typical Memory Layout
In the graphical view, the main flash begins at address 0x0000 0000
because
flash memory is typically memory mapped at that location on EFR32 devices.
However, some devices may have the main flash located at a different address.
See the reference manual of your selected device for the exact memory location
of flash and RAM.
Section Details#
Different memory sections are described starting with the lowest memory address.
Bootloader#
An application using the Simplicity SDK can optionally choose to use a bootloader. When using a bootloader, an area of flash will be reserved for the bootloader and will be unavailable for the application code. Some devices will have dedicated bootloader flash areas, while other devices will have to use parts of the main flash for bootloader code. All series-2 devices use the first parts of main flash for the bootloader.
To allocate flash memory for the bootloader with the Simplicity SDK, add the
bootloader_interface
component to the application. The presence of this
component in the project will trigger the reservation of a fixed size
bootloader. On the EFR32xG21 device the bootloader size is 16 kB while on
EFR32xG22 the bootloader size is 24 kB.
For a different size bootloader, manual modifications of the auto-generated linker files is needed. See the Bootloader user guide UG266 for more Bootloader-specific documentation.
Code#
Application code is next in the memory layout. This is where functions and read only data are placed.
Bootloader Storage#
The application Bootloader has the option to use parts of main flash on the
device as storage space for the firmware update images. To safely reserve space
in the memory map, the application can include the flash_storage
component.
This component will provide source code and a configuration file that the
application can use to tune the amount of storage needed.
When including the flash_storage
component, the default flash reservation is
half of the main flash size minus 16 kB. To modify the size, change the
SL_BOOTLOADER_STORAGE_SIZE
option, which is located in the
sl_storage_config.h
configuration file. The size of the bootloader storage
area is highly application-dependent and should be a fixed size once a product
with a bootloader is deployed.
Note that the configured bootloader storage size used when building the application and the bootloader storage size used when building the bootloader must match. The user will have to manually ensure that the bootloader storage size and location is correctly configured between the bootloader project and the application project.
NVM3#
Simplicity SDK provides a way to store persistent key-value objects into the main flash. This data is persistent between resets and firmware updates and can be used for general storage and in wireless applications for token storage. When you add NVM3 as a component to a project, parts of main flash are reserved for a single NVM3 instance. The NVM3 storage will be placed at the end of main flash and the size of the NVM3 region is configurable by the application. The default size of the NVM3 instance is 40 kB.
The configuration for the NVM3 instance is placed in the file
nvm3_default_config.h
, which is copied into the project when a project is
generated. The NVM3 size configuration is called NVM3_DEFAULT_NVM_SIZE
. For
more documentation on NVM3 and other NVM3 related configurations, see
application note AN1135: Using Third Generation Non-Volatile Memory (NVM3) Data
Storage.
Stack#
The stack and heap are used by the application to allocate dynamic memory. The stack is normally used to allocate local memory to function variables and call frames, which means that applications with deep call stacks will typically need to allocate a larger stack than applications with shallow call stacks. With Simplicity SDK, customer applications can configure the size of the stack.
An application will have to configure the stack size based on the estimated maximum stack usage. This number can be difficult to determine exactly and might change between SDK releases and application versions, so a normal strategy would be to over-allocate the stack space to have some head room for application changes. Always change the stack configuration from the default value to suit the application needs.
The size of the stack is configured in the sl_memory_config.h
configuration
file using the SL_STACK_SIZE
option. This configuration file is copied to the
application when it's first generated. Modifying this configuration option will
modify the stack size accordingly.
When using the Simplicity SDK, the stack memory region is placed at the beginning of RAM. The stack is placed here so that it grows down towards address 0x20000000, which is the beginning of RAM so that stack overflow situations can be detected in hardware without corrupting any data. If at any point, the application uses more stack than is allocated, the device will trigger a fault and the developer can detect this error condition during development.
Heap#
Whenever an application uses malloc()
in any part of the software, a portion
of RAM needs to be allocated to the central heap. The size of the allocated heap
is application dependent. Small applications might not need any heap at all
while other applications might use a lot of heap. The heap region is placed after
the rest of the RAM-based content and the heap is growing towards the end of RAM.
Support for Ember Style Memory Layout#
The memory layout described here for Silicon Labs device is not always
compatible with previous versions of the SDK. The Ember bootloader for the early
EFR32 devices relied on a specific memory layout where the SIMEE section was
placed in the middle of the main memory if the main flash was used for firmware
update storage. To build a project using the Ember style memory layout,
the application needs to pull in a legacy_bootloader_interface
component.
Using this Ember style memory layout will also place an Application Address
Table (AAT) at the start of the application flash, which was required by the
Ember bootloader.