Skip to main content
Explorer
December 14, 2021
Question

jump to another app explanation

  • December 14, 2021
  • 2 replies
  • 1078 views

I have this code:

void bootloader_jump_to_app(void){
	pFunction Jump;
	uint32_t JumpAddress;
 
	HAL_RCC_DeInit();
	HAL_DeInit();
 
	JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);
	Jump = (pFunction)JumpAddress;
 
	__set_MSP(*(__IO uint32_t*)APP_ADDRESS);
	Jump();
 
	SCB->VTOR = FLASH_BASE | 0x00008000;
}

For me, does not make sense the last line as in theory this is not called after jump application, however, commenting this line make a hard fault handler after jump function execution.

    This topic has been closed for replies.

    2 replies

    JCuna.1Author
    Explorer
    December 14, 2021

    making more testing, I realized that changing the line SCB->VTOR = FLASH_BASE | 0x00008000; for asm("nop"); still making the code work. So problem is related if there is no last line of code in the function.

    Here is the asm code:

    419 	HAL_RCC_DeInit();
     bootloader_jump_to_app:
    080006a8: push {r3, lr}
    080006aa: bl 0x800212c <HAL_RCC_DeInit>
    420 	HAL_DeInit();
    080006ae: bl 0x8001990 <HAL_DeInit>
    422 	JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);
    080006b2: ldr r3, [pc, #16] ; (0x80006c4 <bootloader_jump_to_app+28>)
    080006b4: ldr r2, [pc, #16] ; (0x80006c8 <bootloader_jump_to_app+32>)
    080006b6: ldr r3, [r3, #0]
    425 	__set_MSP(*(__IO uint32_t*)APP_ADDRESS);
    080006b8: ldr r2, [r2, #0]
     333 __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
    080006ba: msr MSP, r2
    426 	Jump();
    080006be: blx r3
    428 	asm("nop");
    080006c0: nop 
    080006c2: pop {r3, pc}
    080006c4: strh r4, [r0, #0]
    080006c6: lsrs r0, r0, #32
    080006c8: strh r0, [r0, #0]
    080006ca: lsrs r0, r0, #32

    and here the asm code, when there is no instruction after jump();

    419 	HAL_RCC_DeInit();
     bootloader_jump_to_app:
    080006a8: push {r4, lr}
    080006aa: bl 0x800212c <HAL_RCC_DeInit>
    420 	HAL_DeInit();
    080006ae: bl 0x8001990 <HAL_DeInit>
    422 	JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);
    080006b2: ldr r3, [pc, #16] ; (0x80006c4 <bootloader_jump_to_app+28>)
    080006b4: ldr r2, [pc, #16] ; (0x80006c8 <bootloader_jump_to_app+32>)
    080006b6: ldr r3, [r3, #0]
    425 	__set_MSP(*(__IO uint32_t*)APP_ADDRESS);
    080006b8: ldr r2, [r2, #0]
     333 __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
    080006ba: msr MSP, r2
    426 	Jump();
    080006be: ldmia.w sp!, {r4, lr}
    080006c2: bx r3
    080006c4: strh r4, [r0, #0]
    080006c6: lsrs r0, r0, #32
    080006c8: strh r0, [r0, #0]
    080006ca: lsrs r0, r0, #32

    JCuna.1Author
    Explorer
    December 14, 2021

    Looks like ldmia.w sp!, {r4, lr} is causing the problem. This is making an increment stack pointer after loading process is stack pointer, and in consequence, changing the recent assignation of main stack pointer before to jump to the app. Optimization process (actually using -oS optimization) is adding this instruction. So adding a nop instruction avoid to make this optimizations.

    Graduate II
    January 15, 2022

    When changing the stack pointer, software must use an ISB instruction immediately after the MSR instruction. This ensures that instructions after the ISB instruction execute using the new stack pointer. See ISB

    https://developer.arm.com/documentation/dui0552/a/the-cortex-m3-processor/programmers-model/core-registers

    If the program updates the value of the VTOR, use a DSB instruction to ensure that the new vector table is used for subsequent exceptions.

    https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Processor/Memory-model/Software-ordering-of-memory-accesses