Add new Memory Sections and Segments

From SEGGER Wiki
Jump to: navigation, search

In Embedded Studio you can place functions and variables at given addresses using memory sections and segments.

This page describes the use of Section Placement files for use with the GNU Linker. The SEGGER Linker, which is also part of Embedded Studio features some simpler and more flexible methods to control symbol placement. Refer to the SEGGER Linker User Guide.

Memory Map File

The Memory Map File defines which memory segments are available.

The Memory Map File to use is set in the Project Options -> Code -> Build -> Memory Map File

In the simple case, this is one segment for each flash, and one segment for each RAM.

 <!DOCTYPE Board_Memory_Definition_File>
 <root name="DeviceName">
   <MemorySegment name="FLASH" start="0x00000000" size="0x00040000" access="ReadOnly" />
   <MemorySegment name="RAM" start="0x20000000" size="0x00004000" access="Read/Write" />
 </root>

For more complex firmwares, the memory map can be further refined. For example to split the flash into sections for bootloader, application, and configuration area:

 <!DOCTYPE Board_Memory_Definition_File>
 <root name="DeviceName">
   <MemorySegment name="BOOTLOADER" start="0x00000000" size="0x00010000" access="ReadOnly" />
   <MemorySegment name="APP" start="0x00010000" size="0x00020000" access="ReadOnly" />
   <MemorySegment name="CONFIG" start="0x00030000" size="0x00010000" access="ReadOnly" />
   <MemorySegment name="RAM" start="0x20000000" size="0x00004000" access="Read/Write" />
 </root>

Instead of in the Memory Map File, the segments can directly be defined Project Options -> Code -> Build -> Memory Segments.

Section Placement File

The Section Placement File defines which sections of the application are linked into which segment from the Memory Map File.

The Section Placement File to use is set in the Project Options -> Code -> Linker -> Section Placement File

By default all read-only sections are placed into FLASH and all read-write sections are placed into RAM.

 <!DOCTYPE Linker_Placement_File>
 <Root name="Flash Section Placement">
   <MemorySegment name="FLASH">
     <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
     <ProgramSection alignment="4" load="Yes" name=".init" />
     <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
     <ProgramSection alignment="4" load="Yes" name=".text" />
     <ProgramSection alignment="4" load="Yes" name=".dtors" />
     <ProgramSection alignment="4" load="Yes" name=".ctors" />
     <ProgramSection alignment="4" load="Yes" name=".rodata" />
     <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
     <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
     <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
     <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
   </MemorySegment>
   <MemorySegment name="RAM">
     <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
     <ProgramSection alignment="4" load="No" name=".fast_run" />
     <ProgramSection alignment="4" load="No" name=".data_run" />
     <ProgramSection alignment="4" load="No" name=".bss" />
     <ProgramSection alignment="4" load="No" name=".tbss" />
     <ProgramSection alignment="4" load="No" name=".tdata_run" />
     <ProgramSection alignment="4" load="No" name=".non_init" />
     <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
     <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
     <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
   </MemorySegment>
 </Root>

As with the Memory Map File, it is possible to further refine the placement, to get full control of where symbols and sections are placed.

For example to place the application into the APP segment, defined above, and some extra symbols into the CONFIG segment:

 <!DOCTYPE Linker_Placement_File>
 <Root name="Flash Section Placement">
   <MemorySegment name="APP">
     <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
     <ProgramSection alignment="4" load="Yes" name=".init" />
     <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
     <ProgramSection alignment="4" load="Yes" name=".text" />
     <ProgramSection alignment="4" load="Yes" name=".dtors" />
     <ProgramSection alignment="4" load="Yes" name=".ctors" />
     <ProgramSection alignment="4" load="Yes" name=".rodata" />
     <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
     <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
     <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
     <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
   </MemorySegment>
   <MemorySegment name="CONFIG">
     <ProgramSection alignment="4" load="Yes" name=".config" />
   </MemorySegment>
   <MemorySegment name="RAM">
     <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
     <ProgramSection alignment="4" load="No" name=".fast_run" />
     <ProgramSection alignment="4" load="No" name=".data_run" />
     <ProgramSection alignment="4" load="No" name=".bss" />
     <ProgramSection alignment="4" load="No" name=".tbss" />
     <ProgramSection alignment="4" load="No" name=".tdata_run" />
     <ProgramSection alignment="4" load="No" name=".non_init" />
     <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
     <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
     <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
   </MemorySegment>
 </Root>

Now a variable can be placed into .config, using the attribute section:

 unsigned int __attribute__((section(".config"))) ConfigVariable;