How to jump between programs in Stellaris

2019-01-18 06:52发布

问题:

I am working on a boot loader for Stellaris LM3S1607 chip. I am using Keil MicroVision4 C compiler. The idea is to create 2 independent firmware that one will update another. In firmware1 i downloaded firmware2 file and write it to flash in address 0x3200. untill here it is working. i also verifed that the data is being written to flash correct. Now i have in flash two applications. one is my uip boot loader and the seoncd one is my main project. i want to know how can i jump from the first program to the second program located in 0x3200.

If someone can help me to jump it will be great. Thanks

回答1:

This will work on any Cortex-M part...

Create an assembler function like:

__asm void boot_jump( uint32_t address )
{
   LDR SP, [R0]       ;Load new stack pointer address
   LDR PC, [R0, #4]   ;Load new program counter address
}

In-line assembler syntax varies; this example is Keil ARM-MDK / ARM RealView.

Then at the end of your bootloader:

// Switch off core clock before switching vector table
SysTick->CTRL = 0 ;

// Switch off any other enabled interrupts too
...

// Switch vector table
SCB->VTOR = APPLICATION_START_ADDR ;

//Jump to start address
boot_jump( APPLICATION_START_ADDR ) ;

Note that APPLICATION_START_ADDR in this case is the base or location address of your linked application code (0x3200 in this case), not the entry point indicated in the link map. The application vector table is located at this address, and the start of the vector table contains the application's initial stack pointer address and program counter (the actual code entry point).

The boot_jump() function loads a stack pointer and program counter from the application's vector table, simulating what happens on reset where they are loaded from the base of Flash memory (the bootloader's vector table).

Note that you must have set the start address in your application code's linker settings to the same as that which the bootloader will copy the image. If you are using the Keil debugger, you will not be able to load and run the application in the debugger without the bootloader present (or at least without manually setting the SP and PC correctly or using a debugger script), because the debugger loads the reset vector addresses rather than the application vector addresses.

It is important that interrupts are disabled before switching the vector table, otherwise any interrupt that occurs before the application is initialised will vector to the application's handler, and that may not be ready.

Be careful of any peripherals that you use in both the application and boot code, any assumptions about reset conditions may not hold if the peripheral registers have already been set by the boot code.