0

I've got a KL17, I'm attempting to write a bootloader to allow for OTA updating. I'm having trouble jumping to user app, this is what I'm attempting.

void JumpToUserApplication(uint32_t userSP, uint32_t userStartup)
{
printf("MSP BEFORE: %x \n", __get_MSP());
printf("PSP BEFORE: %x \n", __get_PSP());

SCB->VTOR = userSP; // SET UP INTERUPT VECTOR TABLE FOR APP
// set up stack pointer
__set_MSP(userSP);
__set_PSP(userStartup);
void (*user_app)(void) = userStartup;
user_app();

printf("BAD MSP AFTER: %x \n", __get_MSP());
printf("BAD PSP AFTER: %x \n", __get_PSP());

}

I call it as such:

JumpToUserApplication(PROGRAM_ADDRESS, (PROGRAM_ADDRESS+0x4));

I expect it to jump to the app, however what happens instead is the boot loader actually restarts as if it goes back to the bootloader reset...

WELCOME TO THE BOOTLOADER! 
MSP BEFORE: 20005fc0 
PSP BEFORE: 20006000 
WELCOME TO THE BOOTLOADER! 
MSP BEFORE: 20005fc0 
PSP BEFORE: 20006000
... and so on. 

Any input is appreciated, thank you!

  • What does this assemble to? It should only be a handful of instructions, and that should be much easier to debug. – Sean Houlihane Oct 09 '19 at 08:11
  • Code is simply br0ken. The PSP value requires `userStartup` to be dividable by 8, but callig it as a function requires it to be an *odd* value (thumb bit set). These 2 requirements cannot be fulfilled at the same time. – Turbo J Oct 09 '19 at 10:04
  • psp being set to the entry point? difficult to try to do this with thumb as depending on the tools and the instruction used you either must have the lsbit set or not. much easier to do with real assembly. call a function with the values, and have real assembly do the rest. – old_timer Oct 09 '19 at 12:16
  • actually not just easier, the only way to insure the code will work. – old_timer Oct 09 '19 at 12:17
  • thanks guys, i'm pretty sure the main issue was in fact the values as indicated by @TurboJ using this array method works well. – Mitchell Jones Oct 09 '19 at 14:41

1 Answers1

0

This method works:

#define PROGRAM_VECTOR_TABLE ((uint32_t *) PROGRAM_ADDRESS)

void jump_to_app(void)
{
    static void (*go_to_app)(void) = 0;
    go_to_app = (void (*)(void))(PROGRAM_VECTOR_TABLE[1]);
    SCB->VTOR = (uint32_t)PROGRAM_VECTOR_TABLE;
    __set_MSP(PROGRAM_VECTOR_TABLE[0]);
    __set_PSP(PROGRAM_VECTOR_TABLE[0]);
    go_to_app();
}

A few changes, however I noticed the vector address to go to app resolved to a different value than I was attempting.