cancel
Showing results for 
Search instead for 
Did you mean: 

Modify the start address 0x800 0000

eancelin
Associate II
Posted on June 26, 2012 at 16:26

Hi,

My microcontroller is a STM32F103CB.

I followed the AN2557 to do an IAP in my software. Everything works fine but now I would like to do something like a dual bank features.

I can flash two firmwares at two different address in flash (for example, one @0x8003000 and the second @0x8006000) but when my IAP software starts (@0x800 0000), if I do the classical test ( if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) ) the first bank will be still OK, so I never start the firmware in the second flash.

Is there a way to set an option to know which ''bank'' is activated?

Is there a way to modify by software the start address (modify the 0x800 0000 address)?

I hope my request is enought clear!!

Regards,

#flash #groundhog-day #start-address #iap #stm32
28 REPLIES 28
Posted on April 08, 2015 at 15:56

Ok, the second entry in the vector table, at +4, contains the address of the Reset_Handler code which the processor jumps too.

You would only need to +1 the address of a symbol if the address were even, as supplied by the .MAP or whatever, to designate that the code is in the THUMB (16-bit) instruction set, because the Cortex-Mx parts can't execute ARM (32-bit) instructions, where the PC is even.

The part, as explained earlier, can only start execution at reset from specific addresses. You can jump to whatever code you want to after it starts, and you can change the Vector Table address.

If your Boot Loader leaves IRQ or DMA actions active when it hands control to the application code, you'd better be prepared to deal with that, otherwise things will break. The best course of action is to tear down whatever the Boot Loader set up before handing over control, or passing enough information to the application so it can take over that role.

When you change the base of the code, you also need to adjust the Vector Table address (SCB->VTOR) typically in SystemInit() to reflect the new base address. The base address should fall on a 512-byte boundary.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hpb
Associate II
Posted on April 24, 2015 at 14:40

Hi clive,

sorry for late answer. I had to do some other work in the meantime. Today I've started to investigate this problem again.

To check the jump to the application I'm using a small code at 0x08000000 which modifies the address of the vector-table and jumps directly to 0x08020000 +4+1  - that's all.

If simple application-software at 0x08020000 is used (e.g. LED-blinking), it works quite fine. Also subroutines and interrupts are working. So, the vector-table seems to be OK. But if LCD-routines are integrated (STM32F429i-DISC), it fails.

I've checked a lot of issues (interrupts, etc.), but didn't find an answer. Has somebody an idea?

Thank you!

grant
Associate III
Posted on April 24, 2015 at 14:53

Hi there

I have used the RTC Backup Registers and test for these in the bootloader. So just before I reset from my IAP...


#include ''stm32f2xx_rtc.h''
#define BKUPREG_UPGRADE_STATUS RTC_BKP_DR0
#define BOOTLOAD_TOKEN 0xB00710AD
// Set Bootloader Token
RTC_WriteBackupRegister(BKUPREG_UPGRADE_STATUS, BOOTLOAD_TOKEN);
// Now perform as software reset...
NVIC_SystemReset();
// We should never get here.

Then at the beginning of my bootloader code...

if(RTC_ReadBackupRegister(BKUPREG_UPGRADE_STATUS) == BOOTLOAD_TOKEN) {
// Make sure there is something there to jump too...
if(FIRST_WORD_OF_IAP_FLASH != BLANK_FLASH_WORD32) {

RTC_WriteBackupRegister(BKUPREG_UPGRADE_STATUS, 0);

bootloaderLaunchIAP();
// we should never get here
while(1);
}
}

With a soft-reset, or using the NRST to pin this works fine. In power up reset of course you will stay in your bootloader. Not 100% sure of your application, but hope this helps. Best regards Grant
Posted on April 24, 2015 at 15:03

Where does this +1 thing come from? The vector address as linked should be the correct address for THUMB code, ie ODD

Fails how? Hard Faults? Incorrect DMA addresses? Infinite loops?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hpb
Associate II
Posted on April 24, 2015 at 16:40

@Elliot: Thank you. But sorry, it didn't help. The bootloader itself seems to work and it performs a jump to the APP. But the APP doesn't work.

@clive1: Without the +1 a jump from BL to the APP doesn't work. I found it out by analyzing the reset-vector of a working software. Example: The MAP-file shows a start-address like this: ''0x080001ac Default_Reset_Handler'', but the content of the hex-file is: ''0x08000004: 0x0800001AD'' - this is ''+1''. So, if the PC of the APP is stored at 0x08020004, I have to load 0x08020005. This has been checked - it works only with +1.

''Fails'' means: Hard Fault. It runs to Default_Handler().

The BL performs SystemInit() before jumping to 0x08020000 (I didn't realized up to now). At 0x08020000, SystemInit() is performed again. Maybe this is the reson? - Up to now it doesn't seem so. A deactivation of SystemInit() at the APP doesn't effect the bad behavior.

... searching is going on ...

Posted on April 24, 2015 at 17:10

NO NOT 0x08020005!!!

There is an ADDRESS STORED AT 0x08020004, in a 32-bit word, this points to the RESET HANDLER. The VALUE will be ODD because it's pointing at THUMB code, as the Cortex-M3 cannot run 32-bit ARM code.

The value in the .MAP is a normalized address, the 0x080201AD is the THUMB address. The processor uses the low order bit to indicate 16-bit vs 32-bit code. The bytes/words in question are stored at the EVEN address.

You don't CALL 0x08020000, it's NOT CODE

The SystemInit() code for the application needs to be consious that it's not being called under reset conditions. The PLL may be running, the flash may require wait states, etc, so tread carefully.

@Elliot: Thank you. But sorry, it didn't help. The bootloader itself seems to work and it performs a jump to the APP. But the APP doesn't work.

@clive1: Without the +1 a jump from BL to the APP doesn't work. I found it out by analyzing the reset-vector of a working software. Example: The MAP-file shows a start-address like this: ''0x080001ac Default_Reset_Handler'', but the content of the hex-file is: ''0x08000004: 0x0800001AD'' - this is ''+1''. So, if the PC of the APP is stored at 0x08020004, I have to load 0x08020005. This has been checked - it works only with +1.

''Fails'' means: Hard Fault. It runs to Default_Handler(). 

The BL performs SystemInit() before jumping to 0x08020000 (I didn't realized up to now). At 0x08020000, SystemInit() is performed again. Maybe this is the reson? - Up to now it doesn't seem so. A deactivation of SystemInit() at the APP doesn't effect the bad behavior.

... searching is going on ...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hpb
Associate II
Posted on April 24, 2015 at 17:47

Sorry. My description was not clear.

To avoid confusion, here is the code which jumps from ''0x08000000'' to ''0x08020000''. This code works. 


 /******************************** M A I N ******************************************/
int main(void)
{
#define APPLICATION_ADDRESS (uint32_t)0x08020000
/******************** Definitions to jump to the application ********************/
void (* const jumpFunction)(void) = (void (*)(void))(APPLICATION_ADDRESS + 4 + 1 );
#define JUMP_TO_APPLICATION_ADDRESS __set_MSP(*(uint32_t*) APPLICATION_ADDRESS);jumpFunction();
// Switch vector table
SCB->VTOR = APPLICATION_ADDRESS;
// Jump ...
JUMP_TO_APPLICATION_ADDRESS
}

Posted on April 24, 2015 at 18:08

Still looks wrong, if you have a valid function pointer at 0x08020005 you've got problems...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 24, 2015 at 18:15

Jumping to 0x08020005 suggests you don't actually have a vector table at the front of you application image.

#include <
windows.h
>
#include <
stdio.h
>
typedef unsigned long uint32_t;
int main(int argc, char **argv)
{
#define APPLICATION_ADDRESS (uint32_t)0x08020000
/******************** Definitions to jump to the application ********************/
void (* const jumpFunction)(void) = (void (*)(void))(APPLICATION_ADDRESS + 4 + 1 );
printf(''%x
'', (void *)jumpFunction);
return(1);
}

You're not calling the ResetHandler function in your application image. Use a debugger, step through the code.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..