cancel
Showing results for 
Search instead for 
Did you mean: 

How to jump from the application to the IAP in order to load in a new application?

Rstua.1
Senior

I have created an IAP to load our application and jump to the application which appears to work as expected when the IAP is run from the IDE Debugger. Now I need a way to jump from the application to the IAP to instigate the loading of a new application. But so far I have not figured out a way to jump from the application to the IAP and run the IAP.

To jump from the IAP to the application I am using this code:

JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
 JumpToApplication = (pFunction) JumpAddress;
 /* Initialize user application's Stack Pointer */
 #if (defined ( __GNUC__ ))
 /* Compensation as the Stack Pointer is placed at the very end of RAM */
 __set_MSP((*(__IO uint32_t*) APPLICATION_ADDRESS) - 64);
 #else
 __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
 #endif
JumpToApplication();

Where APPLICATION_ADDRESS is 0x08000000 which is where the application's vector table starts. This appears to work. So I tried to use similar code to jump from the application to the IAP:

JumpAddress = *(__IO uint32_t*) (0x08071000 + 4);
JumpToIAP = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
#if   (defined ( __GNUC__ ))
/* Compensation as the Stack Pointer is placed at the very end of RAM */
__set_MSP((*(__IO uint32_t*) 0x08071000) - 64);
#else
__set_MSP(*(__IO uint32_t*) 0x08071000);
#endif
JumpToIAP();

Where 0x08071000 is where the IAP's vector table starts. But this does not appear to be working. After executing the JumpToIAP nothing appears to happen. It is expected that with in about 10 seconds the application will have been erased, then a new application uploaded from the SDCard and the application would be jumped to from the IAP. This is what happens when the IAP is run from the IDE debugger.

-thanks

6 REPLIES 6

Perhaps you could use a debugger and step into the code and across the transition?

Watch the processor mode you're in when jumping. ie IRQ context, in an RTOS protected/system or user mode.

Watch that you've set the Vector Table properly via SCB->VTOR, perhaps in SystemInit()

Watch what you're doing with the clocks, if the system is running do you need to reinit the HSE, PLL, etc.

Make sure the entry points are correct.

The Loader/IAP portion would tend to be at the front of flash, ie 0x08000000, with the application, and staged replacement, somewhat deeper into memory.

One approach is to set a magic value in RAM, reset, and let the loader find that, and pull the new image from MicroSD after validating it.

Here we've build SDIO/SDMMC based loaders that use a .DFU file to encapsulate/validate the image in a standard form which can be delivered via USB or SD Card.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Rstua.1
Senior

> Perhaps you could use a debugger and step into the code and across the transition?

Tried that. The Application and the IAP are 2 different projects. So when I debug the Application and jump to the IAP the debugger appears to be lost. I can not even single step with out getting a IDE pop up error. I assume the debugger has some concept of where "it thinks" the executable code should be and inhibits/prohibits debugging out side of that range??

> Watch the processor mode you're in when jumping. ie IRQ context, in an RTOS protected/system or user mode.

I'll have to look into these things as I am not sure what they mean.

> Watch that you've set the Vector Table properly via SCB->VTOR, perhaps in SystemInit()

I set that as the 1st line in my IAP main function and that actually got the IAP working (when starting it using the IDE debugger). But the Application has been working on its own all along. Humm, still, it is the jump from the Application to the IAP that does not work as expected.

> Watch what you're doing with the clocks, if the system is running do you need to reinit the HSE, PLL, etc.

The IOC file used by the IAP is a copy of the IOC file used by the Application. But with many features removed. So it is very likely the remaining active features in the IAP IOC file match that of the Application.

> Match sure the entry points are correct.

I believe they are. But I can double check.

> The Loader/IAP portion would tend to be at the front of flash, ie 0x08000000, with the application, and staged replacement, somewhat deeper into memory.

Again, I"ll have to look into this as I am not sure what it means.

> One approach is to set a magic value in RAM, reset, and let the loader find that, and pull the new image from MicroSD after validating it.

That's interesting. But my problem is that while in the Application, I can not jump to the IAP code. So can not pull a new image from the MicroSD.

... thank you for your suggestions. I'll have to look into some of you comments to better understand them.

Piranha
Chief II

Read more on that approach based on system reset and magic value in RAM:

https://community.st.com/s/question/0D50X0000AFpTmUSQV/using-nvicsystemreset-in-bootloaderapplication-jumps

Rstua.1
Senior

Thanks @Piranha​ & @Community member​ for your suggestions.

I am following up just to add what I did to get this working.

While I could not debug the IAP when jumping from our Application to the IAP (because the IAP is it's own application), I could see where the code was using the disassembler. I noticed it was looping in the weak interrupt infinite loop. So some interrupt was being triggered that was not being taken care of in the IAP. To fix this now, before the jump to the IAP, I call a number of STMicro *DeInit() functions and __disable_irq(). Now the IAP completes its task and pulls in a new image of the Application.

So you got that fragile code working - good! Still the solution presented in a link I posted does it in a much more reliable and easier way. 🙂

Rstua.1
Senior

@Piranha​ , thank you for following up. I appreciate your rigorous approach. Always running the boot loader. So a possible recovery with or without a working Application in flash. Maybe there's a better way for use to reach our field upgrade goal.

Let me back away from my question and describe the entirety of how we install code onto our STMicro processors. We have not done away with the STMicro boot loader. It is still in the processor and will still interact with the (unfortunately) x86 compiled STMicro software tools. This is how we will be programming the STMicro processor with our Main Application and IAP Application. I believe the STMicro boot loader always runs and follows a similar pattern as described by you in your liked-to (above) STMicro Forum thread. Now, in the field our product is expected to plug into another of our products which is ARM based. We would like to perform field upgrades using this combinations. But since it is not x86 base, the current STMicro tools used to program the STMicro processors will not run. And even after many here in the STMicro Forum have asked, it does not sound like STMicro is willing to make versions of these tools which will run on an ARM processor. But, our initial product does contain an SDCard and a USB port! And we can configure that SDCard as a USB mass storage device. This allows us to put new files of our choosing on the SDCard including an updated application. If we do this then tell the Main Application to "jump" to the IAP Application the updated images on the SDCard will be programmed into flash in place of the existing Main Application. Then the IAP will "jump" back to Main. There are procedural precautions we can take to mitigate bricking a device using this technique. But even if we do we will only brick it in the sense we can no longer do a field upgrade. We will still be able to use an x86 based computer and ST-Line pod to re-install the Main and IAP applications as the original STMico boot loader should still exist uncorrupted on the STMicro processor.