cancel
Showing results for 
Search instead for 
Did you mean: 

(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 appreciated.

Robmar
Senior III
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")
 
}

7 REPLIES 7

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
Up vote any posts that you find helpful, it shows what's working..

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
Up vote any posts that you find helpful, it shows what's working..

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.

The fnVector table is at 0x08010000 which is the rom address as specified in the script. at that address + 4 is the correct reset address, but that address is not reaching the debugger. I read that at start the Discovery debugger can miss the reset address, so I changed it to software reset and fixed the reset address in config and it worked.

Maybe the release version would work but I can´t test that until I have the LCD connected and new code debugged.

So my aim is to find out why the Discovery debugger fails to get the correct reset address without me fixing the reset address in debug configuration.

So I wondered if the script could be checked by an expert as its clearly in its own lingo! :D

Bob S
Principal

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.

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
Senior III

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