2

I am working with the stm32f4 Discovery board and I am trying to jump to a section of flash where I will begin executing another program there.The variable ApplicationAddress is 0x08008000. When my code hits this section, the PC goes to 0x0000000 and the system freezes. I am not sure exactly what is going on. Thank you for your time. My code to jump is shown below.

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);  
    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();
5
  • A bunch of questions: What is the contents of the two words at 0x08008000? And are you saying that as soon as Jump_To_Application() is executed the PC ends up at 0? Do you have a debugger setup that can single step at the assembly level? Do you have a serial port that you can dump text to for debug writes? Commented May 10, 2013 at 22:30
  • 1
    There is a solution common to any ARM Cortex-M device, detailed here: stackoverflow.com/questions/14393715/…. This is therefore a duplicate. Commented May 11, 2013 at 19:52
  • I apologize, Clifford, I searched for a similar post, but I did not see this one. Commented May 13, 2013 at 15:05
  • So the assembly method works for returning back to the main program start address @ 0x08000000, but not another program's address @ 0x08008000. Do you know why this could be? Commented May 13, 2013 at 16:16
  • Another thing guys, that I ran into; When you compile the program that you are going to jump to, make sure that you change the settings of that project to start at address 0x<whatever address> you are jumping to. Commented Jul 19, 2013 at 20:57

2 Answers 2

4

Presumably the bit of code that you posted int he question is actually using the MSP stack, so when you execute:

__set_MSP(*(__IO uint32_t*) ApplicationAddress);

that stack gets thrown away and if the Jump_To_Application variable is a local variable (which might have been on the stack if it's a local variable - especially if you're running a non-optimized/debug build) might suddenly be garbage.

to solve this problem, I've used:

void LoadStackAndGo( void* sp, void* entry)
{
    __asm (
        "mov sp, r0 \n"
        "mov pc, r1 \n"
    );
}

which should be easily adaptable to whatever toolchain you're using.

Sign up to request clarification or add additional context in comments.

1 Comment

A Cortex-M executable normally has the vector table at the start address, and the table contains an initial stack pointer and PC. It is therefore only necessary to pass the address of the vector table, and to load SP and PC from the first two 32-bit words. Before doing that it is also necessary to reset the SCB:VTOR register to point to the start address, and before even that to disable interrupts.
1

I had the exact same problem, however my solution:

__set_MSP (*(__IO uint32_t*)ApplicationAddress);

__set_PSP (*(__IO uint32_t*)ApplicationAddress);

and declare the function pointer as static...

static Function jumpToApplication = (Function) * (__IO uint32_t*)(ApplicationAddress + 4);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.