2018-09-14 08:12 AM
We have our application running with the SBSFU feature and are not sure if our linker files are designed correctly.
In our application linker file, the CCMRAM is used :
/* Entry Point */
ENTRY(Reset_Handler)
/* Specify the memory areas */
MEMORY
{
region_SLOT_0 (rx) : ORIGIN = 0x08060000, LENGTH = 0x200
ISR_VECTOR : ORIGIN = 0x08060200, LENGTH = 0x200
FLASH (rx) : ORIGIN = 0x08060400, LENGTH = 0x3FC00
RAM (xrw) : ORIGIN = 0x20001900, LENGTH = 0x1A700
SE_region_SRAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 0
SE_Key_region_ROM (rx) : ORIGIN = 0x08011800, LENGTH = 0
SE_IF_region_ROM (rx) : ORIGIN = 0x0800D200, LENGTH = 0x500
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
/* Highest address of the user mode stack */
_estack = ORIGIN(CCMRAM) + LENGTH(CCMRAM);
/* Generate a link error if heap and stack don't fit into CCMRAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
__ICFEDIT_region_SLOT_0_start__ = ORIGIN(region_SLOT_0);
__ICFEDIT_SE_region_SRAM1_start__ = ORIGIN(SE_region_SRAM1);
__ICFEDIT_SE_Key_region_ROM_start__ = ORIGIN(SE_Key_region_ROM);
__ICFEDIT_intvec_start__ = ORIGIN(ISR_VECTOR);
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(8);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(8);
} >ISR_VECTOR
.SE_IF_Code :
{
KEEP(*se_interface_app.o (.text .text*)) /* Se Interface code */
} >SE_IF_region_ROM
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(8);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(8);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(8);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(8);
} >FLASH
.ARM.extab :
{
. = ALIGN(8);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(8);
} >FLASH
.ARM : {
. = ALIGN(8);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(8);
} >FLASH
.preinit_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(8);
} >FLASH
.init_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(8);
} >FLASH
.fini_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(8);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(8);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(8);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
Is it ok to use only the CCMRAM for the application or is this configuration sub optimal?
2018-09-14 08:13 AM
The SBSFU linker file looks like this:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x2001FFFF; /* end of SRAM2 */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
ISR_VECTOR (rx) : ORIGIN = 0x08000000, LENGTH = 0x200
SB_region_ROM (rx) : ORIGIN = 0x08000200, LENGTH = 0xD000
SE_IF_region_ROM (rx) : ORIGIN = 0x0800D200, LENGTH = 0x500
SE_Code_region_ROM_Start (rx) : ORIGIN = 0x0800D800, LENGTH = 0x0
SE_Code_region_ROM_End (rx) : ORIGIN = 0x08011600, LENGTH = 0x0
SE_Startup_region_ROM (rx) : ORIGIN = 0x0800D700, LENGTH = 0x12000
SE_CallGate_region_ROM (rx) : ORIGIN = 0x0800D804, LENGTH = 0x800
SE_Key_region_ROM (rx) : ORIGIN = 0x08011800, LENGTH = 0x200
SE_region_SRAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 0x1900
SB_SRAM1_region (xrw) : ORIGIN = 0x20001900, LENGTH = 0x1E6FF
SB_SRAM2_region (xrw) : ORIGIN = 0x2001C000, LENGTH = 0x4000 /* 16k */
region_SLOT_1 (rx) : ORIGIN = 0x08020000, LENGTH = 256k /* Sector 5 & 6 - Backup Image */
region_SLOT_0 (rx) : ORIGIN = 0x08060000, LENGTH = 256k /* Sector 7 & 8 - Active Image*/
region_SWAP (rx) : ORIGIN = 0x080A0000, LENGTH = 128k /* Sector 9, Only used temporarily when firmware get's swapped */
}
__ICFEDIT_region_SWAP_start__ = ORIGIN(region_SWAP);
__ICFEDIT_region_SWAP_end__ = __ICFEDIT_region_SWAP_start__ + LENGTH(region_SWAP) - 1;
__ICFEDIT_region_SLOT_0_start__ = ORIGIN(region_SLOT_0);
__ICFEDIT_region_SLOT_0_end__ = __ICFEDIT_region_SLOT_0_start__ + LENGTH(region_SLOT_0) - 1;
__ICFEDIT_region_SLOT_1_start__ = ORIGIN(region_SLOT_1);
__ICFEDIT_region_SLOT_1_end__ = __ICFEDIT_region_SLOT_1_start__ + LENGTH(region_SLOT_1) - 1;
__ICFEDIT_SE_IF_region_ROM_start__ = ORIGIN(SE_IF_region_ROM);
__ICFEDIT_SE_IF_region_ROM_end__ = __ICFEDIT_SE_IF_region_ROM_start__ + LENGTH(SE_IF_region_ROM) - 1 ;
__ICFEDIT_SE_Startup_region_ROM_start__ = ORIGIN(SE_Startup_region_ROM);
__ICFEDIT_SE_CallGate_region_ROM_start__ = ORIGIN(SE_CallGate_region_ROM);
__ICFEDIT_SE_Key_region_ROM_start__ = ORIGIN(SE_Key_region_ROM);
__ICFEDIT_SE_Key_region_ROM_end__ = __ICFEDIT_SE_Key_region_ROM_start__ + LENGTH(SE_Key_region_ROM) - 1;
__ICFEDIT_SE_Code_region_ROM_start__ = ORIGIN(SE_Code_region_ROM_Start);
__ICFEDIT_SE_Code_region_ROM_end__ = ORIGIN(SE_Code_region_ROM_End) - 1;
__ICFEDIT_SB_region_ROM_start__ = ORIGIN(SB_region_ROM);
__ICFEDIT_SB_region_ROM_end__ = __ICFEDIT_SB_region_ROM_start__ + LENGTH(SB_region_ROM) - 1;
__ICFEDIT_SE_region_SRAM1_start__ = ORIGIN(SE_region_SRAM1);
__ICFEDIT_SE_region_SRAM1_end__ = __ICFEDIT_SE_region_SRAM1_start__ + LENGTH(SE_region_SRAM1) - 1;
__ICFEDIT_SB_region_SRAM1_start__ = ORIGIN(SB_SRAM1_region);
__ICFEDIT_SB_region_SRAM1_end__ = __ICFEDIT_SB_region_SRAM1_start__ + LENGTH(SB_SRAM1_region) - 1;
__ICFEDIT_intvec_start__ = ORIGIN(ISR_VECTOR);
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(8);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(8);
} >ISR_VECTOR
/* The progRAM code and other data goes into FLASH */
.SE_IF_Code : { KEEP(*se_interface.c.obj (.text .text*))
} >SE_IF_region_ROM
SE_CORE_Bin :
{
SE_CORE_Bin_start = .;
KEEP(*(SE_CORE_Bin));
SE_CORE_Bin_end = .;
} > SE_Startup_region_ROM
.text :
{
. = ALIGN(8);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_fRAMe)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(8);
_etext = .; /* define a global symbols at end of code */
} >SB_region_ROM
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(8);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(8);
} >SB_region_ROM
.ARM.extab :
{
. = ALIGN(8);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(8);
} >SB_region_ROM
.ARM : {
. = ALIGN(8);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(8);
} >SB_region_ROM
.preinit_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(8);
} >SB_region_ROM
.init_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(8);
} >SB_region_ROM
.fini_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(8);
} >SB_region_ROM
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(8);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(8);
_edata = .; /* define a global symbol at data end */
} >SB_SRAM1_region AT> SB_region_ROM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >SB_SRAM1_region
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >SB_SRAM1_region
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
2018-09-14 08:14 AM
For the SE CoreBin the linker file is:
/* Entry Point */
ENTRY(SE_CallGate)
/* Highest address of the user mode stack */
_estack = 0x2001FFFF; /* end of SRAM2 */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
ISR_VECTOR (rx) : ORIGIN = 0x08011600, LENGTH = 0x200
SE_ROM_region_0 (rx) : ORIGIN = 0x0800D800, LENGTH = 0x4
SE_ROM_region (rx) : ORIGIN = 0x0800DEEC, LENGTH = 0x3500
SE_IF_region_ROM (rx) : ORIGIN = 0x0800D200, LENGTH = 0x500
SE_Startup_region_ROM (rx) : ORIGIN = 0x0800D700, LENGTH = 0x100
SE_CallGate_region_ROM (rx) : ORIGIN = 0x0800D804, LENGTH = 0xD6E8
SE_Key_region_ROM (rx) : ORIGIN = 0x08011800, LENGTH = 0x200
SE_region_SRAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 0x1900
region_SRAM2 (xrw) : ORIGIN = 0x2001C000, LENGTH = 0x4000 /* 16k */
region_SLOT_1 (rx) : ORIGIN = 0x08020000, LENGTH = 256k /* Sector 5 & 6 - Backup Image */
region_SLOT_0 (rx) : ORIGIN = 0x08060000, LENGTH = 256k /* Sector 7 & 8 - Active Image*/
region_SWAP (rx) : ORIGIN = 0x080A0000, LENGTH = 128k /* Sector 9, Only used temporarily when firmware get's swapped */
}
__ICFEDIT_region_SWAP_start__ = ORIGIN(region_SWAP);
__ICFEDIT_region_SWAP_end__ = __ICFEDIT_region_SWAP_start__ + LENGTH(region_SWAP) -1;
__ICFEDIT_region_SLOT_0_start__ = ORIGIN(region_SLOT_0);
__ICFEDIT_region_SLOT_0_end__ = __ICFEDIT_region_SLOT_0_start__ + LENGTH(region_SLOT_0) -1;
__ICFEDIT_region_SLOT_1_start__ = ORIGIN(region_SLOT_1);
__ICFEDIT_region_SLOT_1_end__ = __ICFEDIT_region_SLOT_1_start__ + LENGTH(region_SLOT_1) -1;
__ICFEDIT_SE_IF_region_ROM_start__ = ORIGIN(SE_IF_region_ROM);
__ICFEDIT_SE_IF_region_ROM_end__ = __ICFEDIT_SE_IF_region_ROM_start__ + LENGTH(SE_IF_region_ROM) -1;
__ICFEDIT_SE_Startup_region_ROM_start__ = ORIGIN(SE_Startup_region_ROM);
__ICFEDIT_SE_CallGate_region_ROM_start__ = ORIGIN(SE_CallGate_region_ROM);
__ICFEDIT_SE_Key_region_ROM_start__ = ORIGIN(SE_Key_region_ROM);
__ICFEDIT_SE_Key_region_ROM_end__ = __ICFEDIT_SE_Key_region_ROM_start__ + LENGTH(SE_Key_region_ROM) -1;
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.SE_Startup_Code : {
KEEP ( *se_startup.c.obj (.text .text*))
} > SE_Startup_region_ROM
.isr_vector :
{
. = ALIGN(8);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(8);
} >ISR_VECTOR
/* The progRAM code and other data goes into FLASH */
/*.SE_IF_Code : { KEEP(*se_hardware_stm32f4xx.c.obj (.text .text*)) } > SE_IF_region_ROM*/
.SE_CallGate_Code : { KEEP(*se_callgate.c.obj (.text .text*)) } > SE_CallGate_region_ROM
.SE_Key_Data : { *(.SE_Key_Data) } > SE_Key_region_ROM
.text :
{
. = ALIGN(8);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_fRAMe)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(8);
_etext = .; /* define a global symbols at end of code */
} >SE_ROM_region
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(8);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(8);
} >SE_ROM_region
.ARM.extab :
{
. = ALIGN(8);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(8);
} >SE_ROM_region
.ARM : {
. = ALIGN(8);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(8);
} >SE_ROM_region
.preinit_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(8);
} >SE_ROM_region
.init_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(8);
} >SE_ROM_region
.fini_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(8);
} >SE_ROM_region
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(8);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(8);
_edata = .; /* define a global symbol at data end */
} >SE_region_SRAM1 AT> SE_ROM_region
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >SE_region_SRAM1
BOOTINFO_DATA :
{
. = ALIGN(8);
_sBOOTINFO_DATA = .; /* create a global symbol at BOOTINFO_DATA start */
*(BOOTINFO_DATA) /* BOOTINFO_DATA* sections */
*(BOOTINFO_DATA*)
. = ALIGN(8);
_eBOOTINFO_DATA = .; /* define a global symbol at BOOTINFO_DATA end */
} >SE_region_SRAM1 AT> SE_ROM_region
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >region_SRAM2
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
2018-09-14 08:16 AM
It would be great to get some feedback on our linker file configuration since we are not completely sure if this is the intended or best configuration for a project using the SBSFU mechanism. We are using an STM32F407VGT.
2018-09-14 08:24 AM
Stack alignment is broken
/* Highest address of the user mode stack */
_estack = 0x2001FFFF; /* end of SRAM2 */
Should be _estack = 0x20020000, that would meet 4 and 8-byte alignment requirements, and predecrements
2018-09-17 03:01 AM
Ok thanks for this.
Is our usage of CCMRAM in the main application correct?