cancel
Showing results for 
Search instead for 
Did you mean: 

How do execute a program from a location other than the beginning of flash memory?

Gordon Madden
Associate III
Posted on June 24, 2017 at 00:04

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!

1 ACCEPTED SOLUTION

Accepted Solutions
Posted on June 24, 2017 at 01:45

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

15 REPLIES 15
Posted on June 24, 2017 at 01:45

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Zt Liu
Senior III
Posted on June 24, 2017 at 01:46

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.

Gordon Madden
Associate III
Posted on June 24, 2017 at 02:57

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)

0690X00000607RPQAY.png

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).

0690X00000607L8QAI.png

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!

Posted on June 24, 2017 at 01:53

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 24, 2017 at 02:03

Nice catch!

I forgot the remap mechanism!

Posted on June 24, 2017 at 18:03

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 18, 2017 at 00:32

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!

Posted on July 18, 2017 at 02:27

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 18, 2017 at 06:34

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!