This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32L4: Bootloader Jump to App fails depending of optimization level

Hello,

I am trying to write a bootloader for STM32L496(ZGT) and I am pretty new to ARM and RTX.
The Bootloader works over USB HID and uses RTX5 (RTOS 2).
I use µVision V5.36 with compilter V6.16 (With AC5 like warnings).

I encounter a strange behavior.
If I use optimization level o0 my Jump function "failes". I jump but get stuck in the main app. As far as I know at some point where some IRQ should be disabled.
If I use level o1 it jumps.

My Jump funcion:

typedef void (*pFunction)(void);

void JumpToApplication(uint32_t uiAppAdress)
 {
     uint32_t JumpAddress = *(__IO uint32_t*)(uiAppAdress + 4);
     pFunction Jump       = (pFunction)JumpAddress;
 
     HAL_RCC_DeInit();
     HAL_DeInit();
    
         NVIC->ICER[ 0 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 1 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 2 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 3 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 4 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 5 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 6 ] = 0xFFFFFFFF ;
         NVIC->ICER[ 7 ] = 0xFFFFFFFF ;

         NVIC->ICPR[ 0 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 1 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 2 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 3 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 4 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 5 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 6 ] = 0xFFFFFFFF ;
         NVIC->ICPR[ 7 ] = 0xFFFFFFFF ;
        
         SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk ;
    
         SCB->SHCSR &= ~( SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk ) ;
    
     SysTick->CTRL = 0;
     SysTick->LOAD = 0;
     SysTick->VAL  = 0;
 
     SCB->VTOR = uiAppAdress;
 
         __set_CONTROL(0x00000000);
    
     __set_MSP(*(__IO uint32_t*)uiAppAdress);
     Jump();
 }

Maybe anyone has an idea why it get stucks?

Thanks Stefan

  • Did you see:
    https://developer.arm.com/documentation/ka002218/latest/

    As far as I know, these routines work with any compiler optimization level. If not, please check the resulting code and let us know which part gets optimized out of the code.

  • My guess is, with optimization level 0 the compiler puts some values on the stack and uses them when calling "Jump()", However, when the MSP is changed, that values on the stack are gone. With optimization level above 0 it is more likely, the compiler holds values in registers and so the code runs independent of the stack, which still makes things work.

  • Thanks for the information,

    the problem is, that I jump in the hardfault handler of the main application (not bootloader!).

    Hans, I build it complete the way the side said, but now I have the same problem in level o1.
    I use USB, but I have not acitvated any interrupt for USB.

    Andreas, any idea how I can find out which values in which registers this might be?

    Thanks, Stefan 

  • Sorry guys,

    thanks for your help, it worked, missed a line.

    Thanks Stefan