0
\$\begingroup\$

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:

Bootloader jump to main application problem using STM32 with Keil Uvision

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

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 ) ;
}

JumpAddress=(FLASH_WRITE_ADDRESS+4);
JumpToApplication =(void(*)(void))(*((uint32_t*)JumpAddress));
__set_MSP(*(__IO uint32_t*)FLASH_WRITE_ADDRESS);
JumpToApplication();

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

/* Jump to user application */
JumpAddress = *(volatile uint32_t*)(FLASH_WRITE_ADDRESS+4);
JumpToApplication = (pFunction) JumpAddress;
__set_MSP((*(volatile uint32_t*) FLASH_WRITE_ADDRESS));
now_pointer=__get_MSP();
JumpToApplication();

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

This is one second before jump to application code:

And this is result of jump to application code:

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

\$\endgroup\$
10
  • 1
    \$\begingroup\$ So far you've not really provided anything to differentiate your question from the linked one, so it really should be closed as a duplicate. Note that as always, the best-practice advice is to set a flag, do a reset, and then on reset jump to the application before doing any chip configuration. Additionally your question is unanswerable unclear as the storage type of JumpAddress is not given anywhere, nor have you done anything to demonstrate that they transferred payload has been correctly written to flash, or that it was correctly linked for that address to begin with. \$\endgroup\$ Oct 22, 2019 at 21:33
  • \$\begingroup\$ 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 \$\endgroup\$ Oct 22, 2019 at 21:53
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Oct 22, 2019 at 22:09
  • \$\begingroup\$ 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. \$\endgroup\$
    – old_timer
    Oct 23, 2019 at 0:51
  • \$\begingroup\$ 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. \$\endgroup\$
    – old_timer
    Oct 23, 2019 at 0:54

3 Answers 3

0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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();
__set_MSP((*(volatile uint32_t*) FLASH_WRITE_ADDRESS));

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Oct 26, 2019 at 21:17
  • \$\begingroup\$ 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 \$\endgroup\$ Oct 26, 2019 at 21:23
0
\$\begingroup\$

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 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Jun 26, 2020 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.