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
{
ER_IROM1 APPLICATION_ADDRESS ANY_SIZE 0x750
{
.o (RESET, +First)
*(InRoot$$Sections)
.ANY2 (+RO)
}
FW_INFO FW_INFO_ADDRESS FIXED
{
*(FW_Info, +First)
}
ER_IROM2 +0
{
.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)
}
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
{
.ANY (+RW +ZI)
}
ERROR_MEMORY +0
{
*(errmem)
}
SCOPE_MEMORY +0
{
*(scope)
}
STACK_REAL +0
{
stm32xx_STLmain.o (STACK_BOTTOM)
*(STACK)
}
}
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 = .;
} > rom
.stringtable :
{
. = ALIGN(4);
*(message)
*(error_strings)
} > rom
.paraDescriptor :
{
. = ALIGN(4);
PROVIDE (paraDescriptor_start = .);
KEEP (*(para_descriptor))
PROVIDE (paraDescriptor_end = .);
} > rom
PROVIDE (paraDescriptor_size = SIZEOF(.paraDescriptor));
.error_descriptor :
{
. = ALIGN(4);
KEEP (*(error_descriptor))
} > rom
.error_sources :
{
. = ALIGN(4);
KEEP (*(error_sources))
} > rom
.error_reactions :
{
. = ALIGN(4);
KEEP (*(error_reactions))
} > rom
.paradataflash (NOLOAD):
{
KEEP (*(.paradataflash))
} > paraflash
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 = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
.errmem (NOLOAD) :
{
. = ALIGN(4);
*(.errmem .errmem.*)
} > ram
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
.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 ;
}
int32_t error_descriptor_size
int32_t error_sources_size
int32_t error_reactions_size
int32_t error_reactions_start
int32_t error_sources_start
int32_t error_descriptor_start