Skip to main content
Robmar
Senior II
November 10, 2022
Question

(Solved) My arm_gcc_link script (32F407VGT6U) is not passing the correct fnVector table address. With the script below the MCU is not resetting to the correct location. The fnVector table is at rom address, 0x08010000, any guidance would be appreciat

  • November 10, 2022
  • 3 replies
  • 1391 views
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
 
/* Internal Memory Map*/
 
MEMORY
 
{
 
	rom (rx) : ORIGIN = 0x08010000, LENGTH = 1024k - 64k
 
	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128k
 
	ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 64k
 
}
 
 
 
_estack = ORIGIN(ram) + LENGTH(ram) -8; /* -8 keeps older bootloaders (before 2.0.2-HAL) happy */
 
 
 
SECTIONS
 
{
 
	.text :
 
	{
 
 PROVIDE(_linker_isr_loc = .);
 
 KEEP(*(.isr_vector))
 
 *(.text*)
 
 
 
 KEEP(*(.init))
 
 KEEP(*(.fini))
 
 
 
 /* .ctors */
 
 *crtbegin.o(.ctors)
 
 *crtbegin?.o(.ctors)
 
 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
 
 *(SORT(.ctors.*))
 
 *(.ctors)
 
 
 
 /* .dtors */
 
 *crtbegin.o(.dtors)
 
 *crtbegin?.o(.dtors)
 
 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
 
 *(SORT(.dtors.*))
 
 *(.dtors)
 
 
 
 *(.rodata*)
 
 
 
 KEEP(*(.eh_fram e*))
 
	} > rom 
 
	
 
	.ARM.extab : 
 
	{
 
 *(.ARM.extab* .gnu.linkonce.armextab.*)
 
	} > rom 
 
	
 
	__exidx_start = .;
 
	.ARM.exidx :
 
	{
 
 *(.ARM.exidx* .gnu.linkonce.armexidx.*)
 
	} > rom 
 
	__exidx_end = .;
 
	__etext = .;
 
	
 
	/* _sidata is used in coide startup code */
 
	_sidata = __etext;
 
	
 
	.data :
 
	{
 
 __data_start__ = .;
 
 
 
 /* _sdata is used in coide startup code */
 
 _sdata = __data_start__;
 
 
 
 *(vtable)
 
 *(.data*)
 
 
 
 . = ALIGN(4);
 
 /* preinit data */
 
 PROVIDE_HIDDEN (__preinit_array_start = .);
 
 KEEP(*(.preinit_array))
 
 PROVIDE_HIDDEN (__preinit_array_end = .);
 
 
 
 . = ALIGN(4);
 
 /* init data */
 
 PROVIDE_HIDDEN (__init_array_start = .);
 
 KEEP(*(SORT(.init_array.*)))
 
 KEEP(*(.init_array))
 
 PROVIDE_HIDDEN (__init_array_end = .);
 
 
 
 . = ALIGN(4);
 
 /* finit data */
 
 PROVIDE_HIDDEN (__fini_array_start = .);
 
 KEEP(*(SORT(.fini_array.*)))
 
 KEEP(*(.fini_array))
 
 PROVIDE_HIDDEN (__fini_array_end = .);
 
 
 
 KEEP(*(.jcr*))
 
 . = ALIGN(4);
 
 /* All data end */
 
 __data_end__ = .;
 
 
 
 /* _edata is used in coide startup code */
 
 _edata = __data_end__;
 
	} > ram AT > rom 
 
	
 
	.bss :
 
	{
 
 . = ALIGN(4);
 
 __bss_start__ = .;
 
 _sbss = __bss_start__;
 
 *(.bss*)
 
 *(COMMON)
 
 . = ALIGN(4);
 
 __bss_end__ = .;
 
 _ebss = __bss_end__;
 
	} > ram 
 
 
 
	.heap (COPY):
 
	{
 
 __end__ = .;
 
 _end = __end__;
 
 end = __end__;
 
 *(.heap*)
 
 __HeapLimit = .;
 
	} > ram 
 
	
 
	/* .stack_dummy section doesn't contains any symbols. It is only
 
	* used for linker to calculate size of stack sections, and assign
 
	* values to stack symbols later */
 
	.co_stack (NOLOAD):
 
	{
 
 . = ALIGN(8);
 
 *(.co_stack .co_stack.*)
 
	} > ram 
 
	
 
	.ccm (NOLOAD) : {
 
 . = ALIGN(4);
 
 _sccmram = .;
 
 *(.ccm)
 
 . = ALIGN(4); 
 
 _eccmram = .;
 
	}>ram1
 
	
 
	/* Set stack top to end of ram , and stack limit move down by
 
	* size of stack_dummy section */
 
	__StackTop = ORIGIN(ram ) + LENGTH(ram );
 
	__StackLimit = __StackTop - SIZEOF(.co_stack);
 
	PROVIDE(__stack = __StackTop);
 
	
 
	/* Check if data + heap + stack exceeds ram limit */
 
	ASSERT(__StackLimit >= __HeapLimit, "region ram overflowed with stack")
 
}

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
November 10, 2022

Use the CODE posting tool, dumping it in the message body just removes all formatting. See </> icon below editor window.

Not sure many here want to unpick linker scripts in isolation from any other detail.

Check the .MAP file

Check SystemInit() is setting the appropriate SCB->VTOR, ideally by using linker symbols not defines.

Changing settings in the linker script doesn't alter behaviour of the MCU, just directs the linker how it should construct and section the image.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
November 10, 2022

The MCU, which you don't mention, boots from a table mapped at address ZERO, this can be impacted by the state of the BOOT pins, perhaps Option Byte and banking mapping/swapping options, and the System Loader determining which bank does/doesn't not have a legitimate image.

Step back and explain your situation better, with context and detail..

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Robmar
RobmarAuthor
Senior II
November 10, 2022

The MCU is 32F407VGT6U, the program is an example from 2018 that was for the Discovery board. I can get it to run by fixing the Debug configuration start address, apart from that I have no idea why it´s not getting the correct address.

I had read that this is controlled by the linker script. which is the usual case.

I read that the align(4) in the script can cause a problem, and should be replaced with aligh(256) but I don´t know why. I've experience with Intel, Motorola and Arduino IDEs, but am a just 2 days into using STM32CubeIDE.

Bob S
Super User
November 10, 2022

It looks like you intend to run your code with your own bootloader? Otherwise, why you start your code at 0x08010000?

0x08010000 is a non-standard location for the VTOR. As @Community member​ said, on reset the CPU looks at address 0x0 for the vector table/reset vector. If the boot mode is "boot from FLASH" then address 0x0 is mapped to FLASH at 0x08000000. If there is no reset vector there, the CPU will never get to your VTOR at 0x08010000 and your init code will never run to change the VTOR pointer.

I don't know that the debugger is smart enough to look where your vector table ACTUALLY is, and (my guess) probably just always looks at 0x08000000 to emulate a hardware reset.

Robmar
RobmarAuthor
Senior II
November 11, 2022

Hi Bob, as far as I know there is a boot loaded, but its not showing as a sub-project, if I have that right. I just a few hours into using STM, so not up to speed exactly.

I see that I can change a variable in the system_stm324xx.c file to define a fixed address for the VTOR table, but I have the feeling that this isn't the right way to fix this, as I guess the bootloader should be first called, then it is set to call the app's reset entry point, right?

Robmar
RobmarAuthor
Senior II
November 11, 2022

Looks like the bootloader import failed in STMCubeIDE for some reason, I think that fixing this will solve the problem. Thxs for your help.