AnsweredAssumed Answered

Hard Fault Error when jumping from Custom Bootloader to FreeRTOS Appcode for the 2nd time

Question asked by mret on Oct 27, 2016
Latest reply on Oct 27, 2016 by Clive One
Hi, 

I've read a ton of forum posts here regarding hard fault error encountered when jumping from custom BL to App. But, in my case, it's working fine the first time I did the jump to App. But, when I jump back to BL and then jump back to App, the code will encounter a hard fault error in the Appcode before it enters main() function.

The sequence is like this: Reset - Bootloader - Jump to App - Jump to Bootloader  - Jump to App (but the app main() never execute this time due to hard fault error).

I tried removing the freertos in the appcode and the above sequence worked fine. But I need to make it work with freertos.

Any idea what could be the problem here? I suppose the vector table, jump addresses are correct since they worked fine the first time. I'm also disabling the interrupt, setting the stack pointer, before I do the jump.

Here's the code snippet:

void jumpToUserCode(void)
{
  /* Create pointer to usrmain address*/
  typedef void (*funcEntryPtr)(void);
  uint32_t jumpAddr = *(volatile uint32_t*)(APP_ADDRESS + 0x04); /*First word is the SP value, next word is the reset vectore*/
  funcEntryPtr usrMain = (funcEntryPtr) jumpAddr; /*jumpAddr typecasted*/
  
  /*Shut down any tasks running*/
  //HAL_RCC_DeInit();
  //HAL_SPI_DeInit(&hspi1);
  //HAL_DeInit();
  
  /*reset the SysTick Timer*/
  SysTick->CTRL=0;
  SysTick->LOAD=0;
  SysTick->VAL=0;
  SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; /*disable systick interrupt*/
  
  HAL_FLASH_Lock();
  __disable_irq();
  __set_PRIMASK(1); 
  
  /*Setting vector table to APP VTOR*/
  //SCB->VTOR = APP_ADDRESS;
  
  /*Setting main stack pointer to APP_ADDRESS*/
  __set_MSP(*(uint32_t*) APP_ADDRESS);/*Stack pointer (RAM value) default*/
  
  /*Call firmware at jumpaddr (from pointer above)*/
  usrMain();  
}



void jumpToBootCode(void)
{
  
   /* Create pointer to usrmain address*/
  typedef void (*funcEntryPtr)(void);
  uint32_t jumpAddr = *(volatile uint32_t*)(BOOT_ADDRESS + 0x04); /*First word is the SP value, next word is the reset vector*/
  funcEntryPtr usrBoot = (funcEntryPtr) jumpAddr; /*jumpAddr typecasted*/
  
  /*Shut down any tasks running*/
  osThreadSuspendAll();
  //HAL_RCC_DeInit();
  //HAL_SPI_DeInit(&hspi1);
  //HAL_DeInit();
  
  /*reset the SysTick Timer*/
  SysTick->CTRL=0; 
  SysTick->LOAD=0;
  SysTick->VAL=0;
  SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; /*disable systick interrupt*/


  HAL_FLASH_Lock();
  __disable_irq();
  __set_PRIMASK(1);
  
  /*Setting vector table to BOOT VTOR*/
  //SCB->VTOR = BOOT_ADDRESS;
  
  /*Setting main stack pointer to BOOT SP*/
  __set_MSP(*(uint32_t*) BOOT_ADDRESS);/*Stack pointer (RAM value) default*/
  
  /*Call firmware at jumpaddr (from pointer above)*/
  usrBoot();  
}

Outcomes