ParaLib 2.0.15-master SHA: 2e03d68caa
Neccessary Linker settings and initialization to get the parameter-interface working

To use the parameter-interface, the linker must place all parameters in consecutive way in memory. This is done by placing them in a special memory area. For Error ans message system and scope some more linker settings must be done. For complete usage the following linker settinbgs must be done:

  • All Parameters in one region
  • Firmware-Information (CRC and Version) at a special address
  • All strings in a special region (see documaentation of error-system)
  • All errors in a special region (see documaentation of error-system)
  • All error-sources in a special region (see documaentation of error-system)
  • Define special area for Errors
  • Rest of memory for scope memory (see documaentation of scope)

Each toolchain uses a different linker, so the linker settings differs with the target type.

Example for a linker file for the STM32H7 family

LR_IROM1 APPLICATION_ADDRESS APPLICATION_SIZE
{
//Flash-Rom
ER_IROM1 APPLICATION_ADDRESS ANY_SIZE 0x750
{
.o (RESET, +First)
*(InRoot$$Sections)
// high priority any
.ANY2 (+RO)
}
FW_INFO FW_INFO_ADDRESS FIXED
{
*(FW_Info, +First)
}
ER_IROM2 +0
{
// low priority any
.ANY1 (+RO)
}
ER_STRING_TABLE +0
{
*(message)
*(error_strings)
}
ER_ERROR_DESCRIPTOR +0
{
*(error_descriptor)
}
ER_ERROR_SOURCES +0
{
*(error_sources)
}
ER_ERROR_REACTIONS +0
{
*(error_reactions)
}
PARA_DESCRIPTOR +0
{
*(para_descriptor)
}
// Main Memory: AXI-SRAM
// Size: 512 kB
// Content: All Variables that are not directed to any other memory
// At the End a separate Area for the SD_Card is allocated. It is marked in the MPU as not chacheable
RW_IRAM1 AXI_SRAM_START (AXI_SRAM_SIZE - SD_CARD_MEMSIZE)
{;First of Ram -> same address in Bootloader and main Project
;.bss -> no initialization on startup
*(.bss.EthernetStats)
}
RW_IRAM2 +0
{
// RW data
.ANY (+RW +ZI)
}
ERROR_MEMORY +0
{
*(errmem)
}
SCOPE_MEMORY +0
{
*(scope)
}
STACK_REAL +0
{
stm32xx_STLmain.o (STACK_BOTTOM)
*(STACK)
}
}
//Must be a separate Load-Region, to be at the end of BIN-File
LR_CRC +0 4
{
FW_SIZE AlignExpr(+0,4)
{
*(FW_crc, +First)
}
}

Example of a linker-file for Atmel SAM E70

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
MEMORY
{
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x001E0000
ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00060000
paraflash (rw) : ORIGIN = 0x005FFF00, LENGTH = 0xFF
}
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;
HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x200;
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; // End of text section
} > rom
PROVIDE (strings_start = .);
.stringtable :
{
. = ALIGN(4);
*(message)
*(error_strings)
} > rom
PROVIDE (strings_size = SIZEOF(.stringtable));
.paraDescriptor :
{
. = ALIGN(4);
PROVIDE (paraDescriptor_start = .);
KEEP (*(para_descriptor))
PROVIDE (paraDescriptor_end = .);
} > rom
PROVIDE (paraDescriptor_size = SIZEOF(.paraDescriptor));
PROVIDE (error_descriptor_start = .);
.error_descriptor :
{
. = ALIGN(4);
KEEP (*(error_descriptor))
} > rom
PROVIDE (error_descriptor_size = SIZEOF(.error_descriptor));
PROVIDE (error_sources_start = .);
.error_sources :
{
. = ALIGN(4);
KEEP (*(error_sources))
} > rom
PROVIDE (error_sources_size = SIZEOF(.error_sources));
PROVIDE (error_reactions_start = .);
.error_reactions :
{
. = ALIGN(4);
KEEP (*(error_reactions))
} > rom
PROVIDE (error_reactions_size = SIZEOF(.error_reactions));
.paradataflash (NOLOAD):
{
KEEP (*(.paradataflash))
} > paraflash
// .ARM.exidx is sorted, so has to go in its own output section.
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
PROVIDE (sram_start1 = .);
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
PROVIDE (sram_size1 = SIZEOF(.relocate));
// .bss section which is used for uninitialized data
.bss (NOLOAD) :
{
. = ALIGN(4);
PROVIDE (sram_start2 = .);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
PROVIDE (sram_size2 = SIZEOF(.bss));
.errmem (NOLOAD) :
{
. = ALIGN(4);
PROVIDE (errmem_start = .);
*(.errmem .errmem.*)
} > ram
PROVIDE (errmem_size = SIZEOF(.errmem));
//stack section
.stack (NOLOAD):
{
. = ALIGN(8);
PROVIDE (stack_start = .);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
PROVIDE (stack_size = SIZEOF(.stack));
.scopemem (NOLOAD) :
{
. = ALIGN(4);
PROVIDE (scopememory_base = .);
*(scope)
KEEP (*(scope))
} > ram
PROVIDE (scopemem_size = SIZEOF(.scopemem));
. = ALIGN(4);
_end = . ;
_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;
PROVIDE (ram_start = ORIGIN(ram));
PROVIDE (ram_size = LENGTH(ram));
}
int32_t sram_size2
int32_t error_descriptor_size
int32_t strings_size
int32_t ram_start
int32_t stack_start
int32_t strings_start
int32_t sram_size1
int32_t error_sources_size
int32_t error_reactions_size
int32_t error_reactions_start
int32_t errmem_start
int32_t error_sources_start
int32_t stack_size
int32_t error_descriptor_start
int32_t errmem_size
int32_t sram_start1
int32_t sram_start2
int32_t ram_size