cancel
Showing results for 
Search instead for 
Did you mean: 

Boot into multiple main applications?

davidworden9
Associate II
Posted on August 16, 2016 at 15:30

I currently have my own bootloader running with a main application on a STM32F429ZIT.  The internal flash memory is broken down into 3 sections:

1. Bootloader

2. Main Application (Bank A)

3. Temporary storage for new update (Bank B)

For ease of discussion, assume the memory map is as follows:

Bootloader

0x08000000 - 0x0800FFFF

Main App (Bank A)

0x08010000 - 0x0801FFFF

Tempororary storage (Bank B)

0x08020000 - 0x0802FFFF

Currently, when I update the firmware, I store the new hex file in Bank B, and then perform a processor reset.  The bootloader will see the new hex file in Bank B, and perform the following steps:

1. Delete current main application residing in Bank A

2. Copy new hex file from Bank B to Bank A

3. Reset, and go right into the newly updated application in Bank A.

What I am looking to do is eliminate the step 2, which copies the hex file from Bank B to Bank A.  I would like to have the bootloader be able to go to either Bank A or Bank B.

Basically, I want to ping-pong between the two different applications.

For example, if I am currently running from Bank B, I'll store the new update in Bank A.  If I am currently running from Bank A,   I'll store the new update in Bank B.  The bootloader will then jump to whichever one is newer.

So my question is this:

If I compile the main app as if it were being run from Bank A (starting address of 0x08010000), will it matter that the application was compiled with a start address of 0x08010000 but then it is being run from 0x08020000?  I would like to be able to compile the main app, and have it be able to run from either bank when programmed into the chip.  I know at least as a start, the application needs to be aware of what bank it is running in, and adjust the interrupt vector table offset accordingly on the fly

 (SCB->VTOR), 

Thank you!

#stm32f4 #bootloader #c #stm2
4 REPLIES 4
Posted on August 16, 2016 at 16:41

The vector table contains absolute addresses, if your entire application uses relative addressing you'd still need to relocate the vector table by adjusting those addresses in a table you placed in RAM.

In the 2M STM32F4 you can physically swap the memories at 0x08000000 and 0x08100000, allowing code compiled/linked at 0x08000000 to be used.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
davidworden9
Associate II
Posted on August 16, 2016 at 16:58

So for the interrupt table, I believe this should work as a starting point to put the vector table at a certain address. The trouble I'm finding is that I want the main app to be able to be located in either Bank A or Bank B, so I can't really set this offset address during compile time. It would need to be in runtime as soon as I know which bank I'm running from.

Any advice?

void ( * _vectab[80] ) () __attribute__((at(0x08010000))) =
{
(void *)0x00000000, // Empty
__main, // Reset Handler
vec_unimp, // NMI Handler
HardFault_Handler, // Hard Fault Handler
vec_unimp, // MPU Fault Handler
.................
.................
.................
vec_unimp // DMA2 Channel4 & Channel5
};

Posted on August 16, 2016 at 17:12

Having the Initial SP set to zero seems prone to failure.

The processor is always going to start running from the code at 0x08000000, so have your loader code place/copy the new application's vector table in an area of RAM you've carved out for that purpose. While copying you'd ''rebase'' the vector entries to account for where you've placed the code. You'd build the code using ''Position Independent'' settings that the tool-chain provides.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
davidworden9
Associate II
Posted on August 16, 2016 at 18:35

Sorry, bad copy/paste job. Here is the code snippet with the actual stack value.

Regarding the ''position independent'' setting, I am using Keil's uVision, and the options I see are ''Read-Only Position Independent'', and ''Read-Write Position Independent''. I checked both boxes, and I am getting a bunch of errors, so there must be something I'm missing. It added this to the Compiler control string: ''--apcs /ropi/rwpi''

void ( * _vectab[80] ) () __attribute__((at(0x08010000))) =
{
(void *)0x2000fe78, // Top of Stack
__main, // Reset Handler
vec_unimp, // NMI Handler
HardFault_Handler, // Hard Fault Handler
vec_unimp, // MPU Fault Handler
.................
.................
.................
vec_unimp // DMA2 Channel4 & Channel5
};