cancel
Showing results for 
Search instead for 
Did you mean: 

Jumping to Application

Lori B.
Associate III
Posted on May 13, 2014 at 16:53

Hi, I'm quite new with the ARM and STM32 world.

I'm developing an application wich has to load a bootloader and, at a certain point, jump to the main application. I'm using the STM32F4-Disco.

The bootload is quite complex, using FreeRTOS and STemWin, comunicating to an external device with USART periph.

Using a USB OTG drive which han an image.bin file on it (which is the main app code), I load it to a flash memory sector that for me is

APPLICATION_ADDRESS (uint32_t)0x08080000

 and then press a button on the touch-LCD for jumping to the loaded code.

The jumping function is:

cmd_Jump_To_Application(APPLICATION_ADDRESS)

void cmd_Jump_To_Application(uint32_t start_Address)

        {

                    USART_DeInit(USART2);

                    USART_DeInit(USART1);

                    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);

                    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);

                    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);

                    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);

                    RCC_DeInit();

                    __disable_irq();       

        uint32_t addressToJump = *(__IO uint32_t*) (start_Address + 4);

        pFunction Jump_To_Application = (pFunction) addressToJump;

    

         /* Initialize application's Stack Pointer */

         __set_MSP(*(__IO uint32_t*) start_Address);   

         /* Call Reset Handler */

         Jump_To_Application();

        }

Assuming that the downloading part to flash memory is right (I ported from the FW_Upgrade example, and debugging I can see what I expect in the application sector), there is something wrong. When I press the jump button I get a white screen and everything freezing and I can't start the main application.

I'm missing something for sure, maybe about stack or some other vector adress\init, but I can't understand what. Some suggestions? Thanks!
25 REPLIES 25
Lori B.
Associate III
Posted on May 14, 2014 at 17:15

Or that your app code wasn't linked at the right address. Check your Target settings, scatter file or linker script.

 

My app code is located at the right address. It's one of the only things I'm sure about (at least, I hope so) since when debugging and observing memory, I can see the binary information I loaded, in the right place.
chen
Associate II
Posted on May 14, 2014 at 17:54

Hi

''Even supposing I was able to reset setting thins register's bits, If I have my bootloader going to HardFault, I would I know that my bootloader is jumping and that this reset operation will happen?''

You asked 'how do I reset everything?'

My answer was - You can reset all the peripherals by toggling the peripheral reset bits. I recommend this is done as part of the Application start up.

This has nothing to do with your bootloader going into hardfault. The reset will NOT happen automatically as part of hard fault.

''I don't get it. Are you sharing with me some kind of exaple code? If it's like that, I'm not able to see it!''

No, I did not share any code. I cannot, I am working on commercial product and cannot release any code without permission (and I probably will not get permission).

I am sharing with you my knowledge and experience as best I can.

''Here comes the problem. I'm not able to write a singol assembler code line.

I thought I was remapping the vector addresses with line

__set_MSP(*(__IO uint32_t*) start_Address)

Is that right? And, most of all, is it possible to have my project working without knowing assembler language? I'm not so sure about it anymore..''

This line is not assembler - it is pointer/memory access.

Yes, you can get this working without knowledge of assembler.

No, this line is changing the stack pointer - 'MSP' = Main Stack Pointer

Simple explanation of how to jump to another application :

The application should be linked so that the start of the binary is the vector table.

The application should be linked to start on a known address.

The application should be linked to start on an address that is valid for VectorTable.

The first 2 entries in the Vector table are : 1) address of stack for application 2) address of entry point into application.

The bootloader needs to know the address where the application resides.

The bootloader assumes that the application address is the vector table.

The bootloader assumes that the vector table first 2 entries are : 1) address of stack for application 2) address of entry point into application.

The bootloader needs to 1) load the stack pointer with the 1st entry from application vector table

2) load the Program counter with the 2nd entry from the application vector table.

Something like this :

#define APPLICATION_ADDRESS   (uint32_t)0x08020000

    pFunction Jump_To_Application;

    uint32_t JumpAddress;

    /* Jump to user application */

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

    Jump_To_Application = (pFunction) JumpAddress;

    /* Initialize user application's Stack Pointer */

    __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

    Jump_To_Application();

Posted on May 14, 2014 at 18:47

// SVC from User Mode RTOS code into secondary application code - sourcer32@gmail.com
//******************************************************************************
#define APPLICATION_ADDRESS (uint32_t)0x08020000
typedef void (*pFunction)(void);
void SVC_Handler(void) // Replace any others in stm32f1xx_it.c or wherever
{
pFunction Jump_To_Application;
uint32_t JumpAddress;
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();
}
// Invoked with
//
// asm volatile(''svc 0''); // GNU/GCC
//
// __asm(''SVC #0''); // Keil
//******************************************************************************

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Lori B.
Associate III
Posted on May 15, 2014 at 17:48

First of all, I really want to thank you, in particular sung.chen_chung, for explaining and making me understand a lot of thing I never heard about. Thank you!

I finally managed to make the jump. For making it, i compiled the app file with the correct address in options, second thing i defined VECT_TAB_OFFSET in system.c file. The mistake I was making was to define it equal to the address I wanted to jump, but it's an absolute offset. So as I want to jump to 0x08060000, the offset must be 0x00060000.

In this way SCB->VTOR is correctly initialized in the app (sung.chen_chung, now I understand what you were saying!)

But it's not all perfect..Everything is fine when i place my jump function befor GUI_Init() (from STwmWin library). but if I place it just after it, everything get mess.

How can I fix this? I guess it's related to some vector used by STemWin.

Posted on May 15, 2014 at 18:03

How can I fix this? I guess it's related to some vector used by STemWin.

You figure out what STemWin sets up, and what dependencies it creates, be they interrupts, DMA, or whatever.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Lori B.
Associate III
Posted on May 19, 2014 at 10:36

How can I find it out? These info are not in the manual.

chen
Associate II
Posted on May 19, 2014 at 10:58

Hi

''but if I place it just after it, everything get mess.''

Too vague - what actually happens - can you debug it?

Try, disabling all IRQs just before the jump.

Posted on May 19, 2014 at 15:51

How can I find it out? These info are not in the manual.

You do some analysis.

You'd probably start by looking at all the peripherals and interrupts you are setting up. SysTick, TIM, USART, etc. And then whatever BSP related setup you are doing for STemWin.

If that still doesn't help, then dig through the NVIC and see what's enabled in there, and look at the DMA units, and finally the other peripherals.

If things aren't handled within the application then it will probably crash and die. Put proper Hard Fault handlers in your loader and application, so you can catch and diagnose gross failures that dump you there.

If you are new to Cortex parts, get your self the technical manuals (TRM) from ARM, and pick up a copy of one of Joseph Yiu's books on the cores.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Lori B.
Associate III
Posted on May 21, 2014 at 11:06

Hi again!

After doing some tests and debugging, I found out that it wasn't STemWin blocking my app, but instead the USB OTG!

After my main app launches, I get stucked in the USBH_OTG_ISR_Handler

I think that this is because I don' DeInit the USB properly before the jump!

I wrote a function

USBH_Stop(&USB_OTG_Core,&USB_Host);

void USBH_Stop(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)      

{

    

    /* Manage User disconnect operations*/

    phost->usr_cb->DeviceDisconnected();

    

    /* Re-Initilaize Host for new Enumeration */

    USBH_DeInit(pdev, phost);

    phost->usr_cb->DeInit();

    phost->class_cb->DeInit(pdev, &phost->device_prop);

    USBH_DeAllocate_AllChannel(pdev);  

    phost->gState = HOST_DISCONNECTED;

}

but doesn't seem to be enough..Any suggestion?

The jump works well if I unplug the USB drive before doing it!