cancel
Showing results for 
Search instead for 
Did you mean: 

Jump address to choose one of 2 binary in flash

tommelou
Associate II
Posted on April 03, 2014 at 17:49

Hello,

I'm trying to create a bootloader into the component STM32f106RDT with 384KO of Flash.

I have mapped the memory like this:

0x08000000 - 0x0802DFFF for main software (first binary)

0x0802F000 - 0x08030FFF reserved

0x08031000 - 0x0805FFFF for the temp binary (second binary)

My function of bootloader() to jump at selected main address is in flash.

When I debug with keil the pc is in the file startup_stm32f10x_hd.s, then i want to go into my function bootloader so IMPORT the function like this :

; Reset handler

Reset_Handler   PROC

                EXPORT  Reset_Handler             [WEAK]

                IMPORT  __main

                IMPORT  SystemInit

                IMPORT  FLASH_Bootloader       /*my add*/

                LDR     R0, =SystemInit

                BLX     R0              

                LDR     R0, =FLASH_Bootloader  /*my add*/

                BLX     R0                                       /*my add*/

                ;LDR     R0, =__main

                ;BX      R0

                ENDP

The problem is that i want to jump on one of the two binary file. How do i get the flash address of the main() function? If i jump on 0x08000000+4 the beginning of the first binary mapping it does nothing.

Somebody have an idea to select one of my 2 apps and run it?

Thank you.

#stm32 #bootloader
22 REPLIES 22
Posted on April 03, 2014 at 18:11

Presuming your secondary code is built with it's own vector table.

 LDR R0,=0x08031000 /* Or 0x0800000 for the base image */

 LDR R0, [R0, #4] /* Vector+4 for PC */
 BX R0

Plucking out arbitrary functions/addresses within another image is a hazardous task. Remember also that 16-bit THUMB code has ODD addresses, and the M3/M4 cannot run 32-bit ARM code.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tommelou
Associate II
Posted on April 04, 2014 at 09:17

My next function is going in hardfault handler, why?

void FLASH_Bootloader(void)  

{

  __disable_irq();

  JumpAddress = (uint32_t) (void *)0x08000004;

  Jump_To_Application = (pFunction) JumpAddress;

  /* Initialize user application's Stack Pointer */

  __set_MSP(*(__IO uint32_t*) 0x08000000);

      __enable_irq();

  Jump_To_Application();

}

tommelou
Associate II
Posted on April 04, 2014 at 09:30

Is it possible to fix the main() at a specific address? then it will be easy and sure to jump to it in the two binary.

chen
Associate II
Posted on April 04, 2014 at 10:00

Hi

Why enable Interrupts before doing the jump?

I suspect this may be causing the Hardfault - the stack has just been changed and now any IRQ can trigger, which may try to do a context switch on an empty stack

chen
Associate II
Posted on April 04, 2014 at 10:01

Hi

''Is it possible to fix the main() at a specific address? then it will be easy and sure to jump to it in the two binary.''

Yes BUT it is still not the recommended way!

Stick to the method that clive1 suggested.

The code that you posted last does look OK apart from the enable_irq()

Try it without the enable_irq()

tommelou
Associate II
Posted on April 04, 2014 at 10:06

By ODD address, do you mean

JumpAddress = (uint32_t) (void *)0x08000004+1;

?

It still not working.

chen
Associate II
Posted on April 04, 2014 at 10:17

Hi

''By ODD address, do you mean

JumpAddress = (uint32_t) (void *)0x08000004+1;''

I have never really understood clive1's comments about jumping to an odd address.

What you are trying to do is to emulate the boot up process.

The boot process has a pre-determined address to go to (this may be fixed or may be configurable, lets just say it is fixed for now). Lets call this the 'boot vector'

The boot up process takes the first address at the 'boot vector' as the address for the stack.

The next address along at the 'boot vector' is the address of the code to run.

When you compile and link some code on the ARM, usually the linker script will place the vector table first. The first 2 entries in the vector table are : the address for the stack and then the address for the code to run.

So your code should look like this :

void FLASH_Bootloader(void)  

{

  __disable_irq();

  JumpAddress = (uint32_t) (void *) <address of new binary + 4>;

  Jump_To_Application = (pFunction) JumpAddress;

  /* Initialize user application's Stack Pointer */

  __set_MSP(*(__IO uint32_t*) <address of new binary>;

  Jump_To_Application();

}

where <address of new binary> should be 0x08031000

(Check if this address is valid for placing the vector table - see the reference manual for NVIC)

tommelou
Associate II
Posted on April 04, 2014 at 10:37

Thank you for replu sung,

this is exaclty what i mean too. But it still not not working. May be my scatter file mapping is not good.

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************

LR_IROM1 0x08000000 0x00060000  {    ; load region size_region

  ER_IROM1 0x08000000 0x0002F000  {  ; load address = execution address

 

   *.o (RESET,+First)                    ; others

   *(InRoot$$Sections)

   .ANY (+RO)    

   

  }

  ER_IROM2 0x0802F000 0x00001000  {  ; load address = execution address

 

   flash_bootloader.o (+RO)         

   

  }

  RW_IRAM1 0x20000000 0x0000F000  {  ; RW data

   .ANY (+RW +ZI)

  }

  RW_IRAM2 0x2000F000 0x00001000  {  ; RW data

    flash_handle.o (+RO)

    stm32f10x_flash.o (+RO)

  }

}

chen
Associate II
Posted on April 04, 2014 at 11:15

Hi

''May be my scatter file mapping is not good.''

No - do not try to mix your application and bootloader.

Treat the bootloader as one project and the program as another project.

The bootloader can then just treat the program as a binary and not know anything about it.