cancel
Showing results for 
Search instead for 
Did you mean: 

Jumping to program from custom bootloader

DiBosco
Senior
Posted on June 22, 2012 at 20:42

I have nearly got a custom bootloader working which downloads code using RS485 and is encrypted using xtea. I have done the following:

1. Recompiled the original program with the start address as 0x8003000 defined in the linker file.

2. Encrypted the hex file

3. Downloaded the encrypted hex file, decrypted it and programmed the flash.

Now, it looks to me, when I run the debugger the code is correctly programmed into flash from 0x8003000. If I run up a second copy of Crossworks on my laptop with the target program that is recompiled to start at 0x8003000 and run this with the simulator, the code seems to be exactly the same as running the JTAG debugger and looking at what I have programmed with my bootloader.

So, once all the code is downloaded I call this routine:

void JumpToNormalApplication(void)

{

    volatile unsigned long JumpAddress;

    SCB_VTOR = (unsigned long)0x8003000;

    JumpAddress = *(volatile unsigned long*) (0x8003000 + 4);

    Jump_To_Application = (pFunction) JumpAddress;

    Jump_To_Application();

    

}

If I single step through this, it does seem to jump to the right part of code and I can see it executing exactly the same assembler steps that are in thumb_crt0.s. However, it doesn't actually run the target program. I obviously can't really see what is happening in the debugger other than assembler steps so it's difficult to see what is going wrong.

Does anyone have any ideas or tips as to what step(s) I am missing out please?

Many thanks.

7 REPLIES 7
DiBosco
Senior
Posted on June 25, 2012 at 00:45

FWIW I was doing it correctly. There was an optimisation thing going on in my target that was ok in debug mode and being optimised out when I recompiled it for release.

ColdWeather
Senior
Posted on June 25, 2012 at 09:35

You should also init the stack pointer:

 

void JumpToNormalApplication(void)

 

{

 

 

    volatile unsigned long JumpAddress;

 

 

    SCB_VTOR = (unsigned long)0x8003000;

 

   __set_MSP(*(volatile unsigned long*) (0x8003000));

 

    JumpAddress = *(volatile unsigned long*) (0x8003000 + 4);

 

    Jump_To_Application = (pFunction) JumpAddress;

 

    Jump_To_Application();

 

    

 

}

 

The function is implemented in core_cmFunc.h

P.S. I wrote an assembler function for this purpose and placed it into the startup_xxxxxx.s:

VTOR            EQU     (0xE000E000 + 0x0D08)                

StartMainApp    PROC    ; R0 - parameter with the APP vector table address

                EXPORT  StartMainApp               [WEAK]

                MOV32   R1, #VTOR                   ; Load VTOR register address

                STR     R0, [R1]                    ; Store to VTOR to relocate the vector table

                LDR     SP, [R0]                    ; Reinit the user stack

                LDR     R0, [R0, #4]                ; Get the user entry point...

                BX      R0                          ; ... and jump to it

                ENDP

For your case it should be invoked as:

extern void StartMainApp(uint32_t vect);

StartMainApp(0x8003000);

emalund
Associate III
Posted on June 25, 2012 at 17:17

there are many ways to skin a cat; however as far as switching from boot to app I know none better than a reset.

 The jump method is fraught with possibilities for oversight (did you leave this SFR in some state?, did you reset/relocate the stack?, did you ...?)

With a reset everything is in a known state.

Erik
u23
Senior
Posted on June 23, 2014 at 15:25

I have problem with jump to application by bootloader.

The device used is the STM32F105R8.

The bootloader does not jump in the application,it crashes in the function ''Jump_To_Application()''.

The code of the bootloader making the jump is:

#define APPLICATIONADDRESS (uint32_t)0x08008000

/* Test if user code is programmed starting from address ''ApplicationAddress'' */

if (((*(__IO uint32_t*)APPLICATIONADDRESS) & 0x2FFE0000 ) == 0x20000000)

{

/* Jump to user application */

JumpAddress = *(__IO uint32_t*) (APPLICATIONADDRESS + 4);

Jump_To_Application = (pFunction) JumpAddress;

/* Initialize user application's Stack Pointer */

__set_MSP(*(__IO uint32_t*) APPLICATIONADDRESS);

Jump_To_Application();

}

In the application i have relocate the vector table:

int main(void)

{

// __disable_irq();

/* Set the Vector Table base location at 0x8000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);

// __enable_irq();

/***************** Add your application code here ***************************/

........

}

I attached the image (bootloader + application) downloaded from flash.

________________

Attachments :

Img_Boot_Apl.bin : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0zW&d=%2Fa%2F0X0000000biR%2FI9C9IWmrCcywBwSNa.ChQ.ierzPU1EgpirSS1xtbm2Y&asPdf=false
chen
Associate II
Posted on June 23, 2014 at 16:20

Hi

Have you tried disabling all IRQs (especially the SysTick) in the bootloader before the jump?

u23
Senior
Posted on June 24, 2014 at 14:10

yes, i disabled all IRQs.

/* Test if user code is programmed starting from address ''ApplicationAddress'' */

    if (((*(__IO uint32_t*)APPLICATIONADDRESS) & 0x2FFE0000 ) == 0x20000000)

                  {

                            LED_On(LED2);    

                            

                            // Disable all irq

                            __disable_irq();

                            

                            /* Jump to user application */

                            JumpAddress = *(__IO uint32_t*) (APPLICATIONADDRESS + 4);

                            Jump_To_Application = (pFunction) JumpAddress;

                            /* Initialize user application's Stack Pointer */

                            __set_MSP(*(__IO uint32_t*) APPLICATIONADDRESS);

                            Jump_To_Application();

                        }

u23
Senior
Posted on June 25, 2014 at 11:48

I solved!

The solution consist in settings the parameters in application code:

1) In SystemInit function the ''VECT_TAB_OFFSET'' must be equal as 0x7000 (application address - 0x1000);

2) The Application needs to be compiled for the higher address (0x08008000) with size equal 0x9000 (flash size - VECT_TAB_OFFSET);

3) The first istruction in the main must be  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000).