I have written a bootloader for my board, but it generates a hard fault when it jumps to the application code.

My error is like this question:

• microcontroller: stm32f103zet
• software: keil
• BOOT pins: BOOT1 and BOOT2 are 0 (FLASH boot mode)

I did this steps: in application code:

1. I changed ROM address to 0x8030000.
2. I changed VECT_TAB_OFFSET to 0x30000
3. I used of fromelf for creating .bin file

then I wrote a simple code (blinky)

in bootloader code: i receive .bin file with USART and then i write it to address 0x8030000 of FLASH and The following code:

USART_DeInit(USART1);
RCC_DeInit();

__set_CONTROL(ENABLE_PRIVILEGE_MODE);

NVIC->ICER[ 0 ] = 0xFFFFFFFF ;
NVIC->ICER[ 1 ] = 0xFFFFFFFF ;
NVIC->ICER[ 2 ] = 0xFFFFFFFF ;

NVIC->ICPR[ 0 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 1 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 2 ] = 0xFFFFFFFF ;

SysTick->CTRL = 0 ;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk ;

SCB->SHCSR &= ~( SCB_SHCSR_USGFAULTENA_Msk |
SCB_SHCSR_BUSFAULTENA_Msk |
SCB_SHCSR_MEMFAULTENA_Msk );

__disable_irq();

if( CONTROL_SPSEL_Msk & __get_CONTROL( ) )
{  /* MSP is not active */
__set_MSP( __get_PSP( ) ) ;
__set_CONTROL( __get_CONTROL( ) & ~CONTROL_SPSEL_Msk ) ;
}

JumpToApplication();


But it goes to hardfault. So now I use this part of the code:

/* Jump to user application */
now_pointer=__get_MSP();
JumpToApplication();


but it is the same as before. What is problem?

okey.now,i find and solve problem: i put my writing in FLASH mistake picture:

• my question is this.what must i do?you want of me , i say other thing??? i debug my code again and again...i read google notes...i observe github example...but it not work.and i am waiting there for someone,that,had this problem and maybe now can help to me. and about to like question that you said:it have not answer so i ask question again. Chris Stratton – hadisamani1996 Oct 22 '19 at 21:53
• You need to write a proper hard fault handler that will help you diagnose the problem. Look at the fault registers to see what kind of fault occurred and verify that you really know which assembly instruction caused it. Use breakpoints before the offending instruction and then single-step through your code. This is not magic, it's just debugging. Don't expect answers to come from the internet or by staring at the code. – Elliot Alderson Oct 22 '19 at 22:09
• how did you get an odd address in the pc? that gets stripped on the way in. Ideally you want to manually use bx or blx with a small amount of assembly otherwise you have to verify the disassembly is using the right instructions with the right address. – old_timer Oct 23 '19 at 0:51
• what have you done to debug this other than use this debugger which clearly isnt helping. you didnt show the relevant jump to application code. – old_timer Oct 23 '19 at 0:54

Most likely you use the standard start-up code from the STM in the user application. Is sets VTOR to the begining of the FLASH memory. Remove this line and it should work

I find my mistake and i solve it.now my bootloader work correctly

but my problem:

1- i I contracted,change vector address line,after main in application file.

2- i commented this lines in bootloader file:

__disable_irq();


Other than that i had mistake in writting in flash( i not regarding little indian)

and now my code work correctly

thank of all help me to resolve this problem.

• Probably that line was invalidating your reference to JumpAddress - you never answered the question about its storage class. What you are doing now only works because the bootloader and main program have the same RAM layout, should you need to change how the main program uses RAM it may break. – Chris Stratton Oct 26 '19 at 21:17
• yes.maybe it not work if bootloader and main app don't have same RAM. but remember it is my first bootloader app. i can improve it in future=)@ Chris Stratton – hadisamani1996 Oct 26 '19 at 21:23

As cortex m0+ doesn't have some of the fancy 32bit or even 16bit intermediate and as you will compile to even 1K boundary, You just have to point to new vector table by 8bit left shifted.

  if ( firm1 > firm2) __asm("movs r0, #0x40");       // firmware at 0x4000
else __asm("movs r0, #0xa0");                      // for firmware at 0xa000

__asm("lsls r0, r0, #8");
__asm("ldr  r1, [r0]");
__asm("msr  msp, r1");              // Set new MSP
__asm("msr  psp, r1");              // PSP based on SP
__asm("ldr  r1, [r0,#0x4]");
__asm("mov  pc, r1");               // Jump by changing PC

• That's not quite a correct analysis as if instruction widths were the issue, there would be an error during compilation. In actuality compilers do just fine at synthesizing larger constants and indirecting what the hardware cannot do directly. Rather what you may have managed however is to avoid some dependence on the stack which could cause the OP's code to fail after they have changed the MSP, but we never really got implementation details on what the OP's code compiles to. – Chris Stratton Jun 26 '20 at 17:03