2017-06-23 03:04 PM
Using STM32F417, programs uploaded to internal flash start executing at address 0x0800_0000.
I want to start the program at 0x0800_0010 instead. The reason for the extra bytes at the beginning of flash is to save status bytes that indicate the state of the startup or bootloader in case of a failure during firmware updates.
By going into flash options in KEIL uVison, I can change the ROM settings to program to flash starting at that address.
If I then go to the LINK Utility, I can see that the program does indeed start at the new address, but it will not execute.
The program is still probably still starting at the beginning of flash.
Searching through the files in the project, I find various #defines that may or may not affect where the program starts running. I have stepped through the startup sequence and did not see anything with that address that could be changed.
I tried changing the base address for the Ram fro 0x0800_0000 to the new address, thusly:
#define RamAddress (IO_BASE+0x08000010)
How do I get the program to start executing at 0x0800_0010 instead of 0x0800_0000?
Thank you for your help!
Solved! Go to Solution.
2017-06-23 04:45 PM
That's not how the processor works, you don't get to decide.
Use the RAM, BKPRAM, or carve out one of the 16KB blocks at 0x08004000, 0x08008000, or 0x0800C000
The Vector Table (via SCB->VTOR) can be relocated to another address on a 512-byte boundary later.
Put a CRC or checksum around the Boot Loader or Application image so you can validate them. In the case of a corrupt application, don't jump into it, but fall back into a download or recovery mode. Past state from one reset to the next by placing data in RAM. ie Application sets ma-gic value in RAM, resets, boot loader sees this and erases application and downloads or updates new copy. Reset does not clear RAM, power cycling brings it up in a non-specific state.
2017-06-23 04:45 PM
That's not how the processor works, you don't get to decide.
Use the RAM, BKPRAM, or carve out one of the 16KB blocks at 0x08004000, 0x08008000, or 0x0800C000
The Vector Table (via SCB->VTOR) can be relocated to another address on a 512-byte boundary later.
Put a CRC or checksum around the Boot Loader or Application image so you can validate them. In the case of a corrupt application, don't jump into it, but fall back into a download or recovery mode. Past state from one reset to the next by placing data in RAM. ie Application sets ma-gic value in RAM, resets, boot loader sees this and erases application and downloads or updates new copy. Reset does not clear RAM, power cycling brings it up in a non-specific state.
2017-06-23 04:46 PM
If I understand correctly,
the core always starts from 0x00000000 to fetch the initial value for main stack point, then perform the reset handler routine. If you change the ROM setting in your project setting, it really will produce a memory map as you config for THIS Project.
However, a power on reset always starts from 0x00000000.
You may store your status bytes in the image of your boot-loader, or just leave it in last page of ROM, or eeprom if you have it.
2017-06-23 05:57 PM
Thanks for the answers, I'm trying to follow along.
So, first I went to the flash options in KEIL uVision and set the IROM to 0x0800_0010, instead of 0x0800_0000 (below)
In the SystemInit() function in system_stm32f4xx.c file, there is a Vector Table setting for FlashBase
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM*/
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in InternalFLASH*/
#endif
Then I set the #define for the FlashBase (Peripheral Memory Map in stm32f417xx.h) to 0x0800_0010U, instead of 0x0800_0000U (below)
#define FLASH_BASE 0x08000010U /*!< FLASH(up to 1 MB) base address in the alias region*/
I then compiled and loaded the program, but it does not run. Opening the ST-LINK Utility and connecting to the device shows that the program is loaded at 0x0800_0010 (below).
So, changing the #define for the FlashBase doesn't work and I don't understand exactly why.
Above, CliveOne mentions that the VTOR could be changed to another address at a 512 offset.
How would you set the program to start executing at 0x0800_4000 (the next page, 16K later)?
If you can do that, why not at 0x0800_0010?
I will look into using SRAM for saving the state as CliveOne suggests.
Thanks again!
2017-06-23 06:53 PM
Executes from table at zero, but the base of FLASH, RAM or ROM is mapped/shadowed there via the BOOTx pin settings. But it loads a PC from +4 and that address almost always points to the native address of the code, ie
+0 0x20002000 Stack top in RAM
+4 0x08000123 ResetHandler address in FLASH
2017-06-23 07:03 PM
Nice catch!
I forgot the remap mechanism!
2017-06-24 11:03 AM
You don't get to define the address, the processor isn't going to start at 0x08000010 or 0x08004000 just because you want it to. The silicon doesn't provide that functionality.
Put the data some place else.
2017-07-17 05:32 PM
Hi Clive,
What does 'carve out' mean in relation to the Flash pages (if that's what you mean by blocks)?
Does that mean that I can start the application execution, somehow, at page 2 ( 0x08004000 )?From your answer, I thought that was not possible.
I tried leaving a word in SRAM that I don't erase until the upgrade is finished, but in the case of a power interruption,
and reset, there are (potentially) no files left. How can you tell the processor to do something if there is no code?One of my tests left the Flash completely erased and I am unsure how to recover from that scenario.
Thanks for your insight on this!
2017-07-17 07:27 PM
Carve out means to leave a hole, ie the code/text section runs from 0x08000000..0x08003FFF, and then 0x08008000..0x080FFFFF
You do this via your scatter file, or linker script, so the linker leaves a unused hole at the 16KB sector located at 0x08004000..0x08007FFF, which you can then read/write/erase without disturbing your other code and data.
In a robust implementation you'd build at 16KB loader that lives at 0x08000000..0x08003FFF, and place your application code at
0x08008000..0x080FFFFF, leaving 0x08004000..0x08007FFF for your calibration data. If you need more data, push the app deeper into the FLASH.
Then you'd never ever erase the loader, and the loader would only transfer control to the application if the image is validated (checksum, crc, sha-256, or whatever). Leaving the loader alone means there's always something bootable, and the customer can't entirely brick the device.
2017-07-17 11:34 PM
That is the best news I've had all year! I found the ARM Linker User Guide and am reading about scatter files.
Thanks a million!