cancel
Showing results for 
Search instead for 
Did you mean: 

How to Dynamically Change Flash Base Address for OTA Updates Without Hardcoding in Bin File?

satyam9896
Associate II

Hello ST Community,

I am working on an OTA (Over-The-Air) update implementation for an STM32L072 series microcontroller which has 192kb flash memory. In my setup, I have divided the flash memory into three regions: bootloader (starting at 0x08000000), App1 (0x08005000) which will initially running, and App2 (0x0801C000) where first firware binfile will be flash through OTA process. The bootloader handles jumping to the active application( suppose active app is 1 so it will set the msp and jump to that address for example in initial stage the msp is set at app1 address which is 0x08005000), and OTA updates allow switching between App1 and App2 slots( for example ones new fw will be flashed and CRC done the value for active app will be chnaged and will be store in flash and reset and again B.L will check and set msp and jump to that address).

Here is my challenge: When performing OTA updates, the bin file includes a hardcoded vector table offset and flash base address(VECT TABLE OFFSET 0x08005000 and same flash base address ). if a new firmware update is targeted at App2, the bin file assumes the flash base address is 0x0801C000. However, this creates an issue in scenarios where the firmware is deployed to devices that have skipped previous updates (e.g., suppose person A has done with very first update where B has skipped the update but ones second update will come in future the Person B's device, which is still running App1 will have problem bcz the second bin file have hard coded vect offset and flash base address value ). In this case, the new update intended for App2 cannot run because its vector table offset and flash base address conflict with the currently active App1 slot.

I want to avoid relying on hardcoded flash base addresses in the bin file. Instead, I aim to dynamically configure the flash base address and vector table offset at runtime based on the active slot values. This would allow skipped updates to function correctly without introducing mismatches.

Is there a recommended way to achieve this on STM32L0 series devices? Specifically:

  1. Can the FLASH_BASE macro or the vector table offset be adjusted dynamically after firmware deployment?
  2. What modifications are needed in the linker script or firmware to support this functionality?
  3. How can I ensure compatibility with devices that skip one or more updates?

 

file name: system_stm32l0xxc.c

 #define USER_VECT_TAB_ADDRESS
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */

#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET       0x5000U   /*!< Vector Table base offset field.
                                                  //  This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */​

 

Any guidance or suggestions for this dynamic handling of the flash base address would be greatly appreciated!

Thank you!

12 REPLIES 12
MM..1
Chief III

My tip this is waste of energy try doing this safe. More simple and safe is concept with APP0 as factory never rewrited and APP1 as any update. Bootloader can be part of APP0 or separate based on requirments.

but suppose App0 is running and helping in flash of new bin fine download through OTA process and save it at app1 slot but then the VECT offset need to be change dyanmically to addressing the app1 slot on very next reset save and suppose even tho it can be done but as we know that after reset app1 will be running and will help in download the bin file through ota but for that its req to erase the app0 slote first so to make it done we have to change the vect offset dyanicallly to run app1 so that it can perform the erase task. and vive versa form next ownwards updates between slot1 and slot 2.
NOTE: im using stm32l072 which has 192kb flash. and my app code req atleast80kb.

 

satyam9896
Associate II

i belive suppose my application is running at address 0x08005000 so one this must be set is VECT offset which should be 0x5000 and also in keil in configure tool i have o set the the ROM1 start address which nothing but flash i believe and also its size otherwise it wont work ..i have attached the image of the configuration window 

Here is my challange: i want to write this values start and size in code dyanamically so how can i achieve this in stm32l072. 

if i will be able to do this then i can flash any bin file in ota withut hardcode vect offset table value and this config for ROM1 value . 
also i checked but im not able to find this how to change this values in code files.

configure.png

No for every OTA your app need jump back to app0 = factory , then erase OTA1 and load OTA1.

Boot process if found valid OTA1 start it instead factory. ASAP

The vector table contains hard-coded absolute addresses, you'll need to patch the table with relocated addresses.

You could perhaps do this by having the boot loader copy and fix these in RAM, say the base at 0x20000000, and then map SCB->VTOR to that.

The loader would also know/determine the newer app image, and that it's valid/intact, and manage the relocation/hand-over.

A very simple assembler sequence could return the execution address if that's important, and you could build code as "address independent"

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

can you please share any example for this where they will be doing same flow which you exaplined and also any refernce video. it would be helpful.

Actually i have already written my more the 50% code so it would be delay for me to try in that your way.
just please help me out to fix this flash start addressso that i can proceed the ota feature in my product. 
however, like you said app0 will be running and help in top download the bin which is at app1 slot.
suppose consider the scenerio where bootloader and app0 is together in app0 slot and any fw upgrade will happen at slot app1 that mean erase and write at app1 slot which will be perform by app0 only however if suppose first fw upgrade happened at slot app1 so thats means after ever reset boloader will jump to app1 that also means now write,read,erase any fn will be running at app1 slot only but if i want to upgrade again but how i can make it possible at slot1app because the code is already running at it and it is not possible that at the same time it will run and perform also and erase of itsself(slote1).
please clearify how can it be possible .

Place binary into position in memory, that is not compiled for, require precise -fpic switch applied in compiler and linker. Read c - Function Pointers in position independent code (-fpic) on stm32 gcc - Stack Overflow

Because this all i write dont try this.

Compile every upgrade for OTA1 and manage jump back to APP0 from APP1 when upgrade arives....

satyam9896
Associate II

Tell me one thing there is codeA in which nothing but in while(1) LED will Toggle and code has offset table variable set as  0x00005000 and in keil configration setting the start address of IROM1 is : Start ->  0x0801C000 and size: 0xA000 you can see the photo of keil configration setting window above already i have shared. Now, I have compiled the code and generated bin file same Bin I will flash it at address 0x08005000 from mx cube programmer.
In this scenerio suppose my Booloader bin is at address 0x08000000 and as per logic it will help to set msp=0x08005000 and also jump to same reset handler as write below....

 
   void (*app_reset_handler)(void) = (void (*)(void))(*((volatile uint32_t*) (0x08005000+ 4U)));
 
  /* Reset the Clock */
   __HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
  HAL_DeInit();
  HAL_RCC_DeInit();
 
  __set_MSP(*(volatile uint32_t*) 0x08005000);
  SysTick->CTRL = 0;
  SysTick->LOAD = 0;
  SysTick->VAL =  0;
findbootMode =  3;
  
  /* Jump to application */
    app_reset_handler();

my doubt is after reset the code at 0x08005000 will run or not because in my case it is not running but the time i will set keil configration ROM1 Start setting as 0x08005000 and offset will be same as privious 0x0800500 ..the code will run ..led will toggle after reset.
why its so?