cancel
Showing results for 
Search instead for 
Did you mean: 

Jump To Application From

NASI
Senior

Hello,

I am working on a custom bootloader for STM32F105 which it is possible to write a bin file into the flash via CAN bus(CAN2).

My issue is that the part of bootloader to jump to application doesn't work.

Here is the jump function code:

#define MAIN_PROGRAM_START_ADDRESS              0x08002000
 
void JumpToApplication(void)
{
  JumpAddress = *(__IO uint32_t*)(MAIN_PROGRAM_START_ADDRESS + 4);
  Jump_To_Application = (pFunction) JumpAddress;
 
    __HAL_RCC_GPIOC_CLK_DISABLE();
  __HAL_RCC_GPIOD_CLK_DISABLE();
  __HAL_RCC_GPIOB_CLK_DISABLE();
  __HAL_RCC_GPIOA_CLK_DISABLE();
	HAL_RCC_DeInit();
	HAL_DeInit();
	SysTick->CTRL = 0;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
 
    /**
     * Step: Disable all interrupts
     */
    __disable_irq();
 
  __set_MSP(*(volatile uint32_t*) MAIN_PROGRAM_START_ADDRESS);
 
  Jump_To_Application();
}

Function HAL_RCC_DeInit() jumps directly to HardFault_Handler(). I am using an external crystal ocsilator 8MHz.

Without calling HAL_RCC_DeInit(), the Jump_To_Application() jumps directly to HardFault_Handler().

Any idea?

Thank you.

19 REPLIES 19
Javier1
Principal

Hi @NASI​ , i just developed the same thing last year.

Canbus Bootloader for stm32f105 families, it has been working for some time now.

This is my jump to app function:

void jumpToApp(const uint32_t address) {
	const JumpStruct *vector_p = (JumpStruct*) address;
 
	deinitEverything();
 
	/* let's do The Jump! */
	/* Jump, used asm to avoid stack optimization */
	asm("msr msp, %0; bx %1;" : : "r"(vector_p->stack_addr), "r"(vector_p->func_p));
}
void deinitEverything() {
	//-- reset peripherals to guarantee flawless start of user application
	//	HAL_GPIO_DeInit(LED_GPIO_Port, LED_Pin);
	HAL_GPIO_DeInit(CAN1_TX_BOOTLOADER_GPIO_Port, CAN1_TX_BOOTLOADER_Pin);
	HAL_GPIO_DeInit(CAN1_RX_BOOTLOADER_GPIO_Port, CAN1_RX_BOOTLOADER_Pin);
	HAL_CAN_DeInit(_hcan);
	HAL_RCC_DeInit();
	HAL_DeInit();
	SysTick->CTRL = 0;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
}
/////////////////////////////////////////////////////blind jump to memory struct
typedef void (application_t)(void);
 
typedef struct
{
    uint32_t		stack_addr;     // Stack Pointer
    application_t*	func_p;        // Program Counter
} JumpStruct;
//////////////////////////////////////////////////////

 >> I am using an external crystal ocsilator 8MHz.

Gooooood! i didnt and i suffered great deal

we dont need to firmware by ourselves, lets talk

Hi @Javier Muñoz​ ,

I am using also almost the same functions, but calling the HAL_RCC_DeInit() goes wrong, jumps to HardFault_Handler().

did you debugged line by line? (inside HAL_RCC_deinit)

extra idea, are you calling JumpToApplication inside an IRQ? because if you are the systick might be frozen.0693W00000Y7yPaQAJ.png

we dont need to firmware by ourselves, lets talk
NASI
Senior

Yes, I did:

HAL_StatusTypeDef HAL_RCC_DeInit(void)
{
  uint32_t tickstart;
 
  /* Get Start Tick */
  tickstart = HAL_GetTick();
 
  /* Set HSION bit */
  SET_BIT(RCC->CR, RCC_CR_HSION);
 
  /* Wait till HSI is ready */
  while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
  {
    if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
    {
      return HAL_TIMEOUT;
    }
  }
......

The first line "tickstart = HAL_GetTick();" jumps to fault handler

NASI
Senior

No, I am calling JumpToApplication from main().

somthing fishy is going on with your systick

we dont need to firmware by ourselves, lets talk

place a HAL_Delay(100): in main does it fail also?

we dont need to firmware by ourselves, lets talk
NASI
Senior

Yes, It does

there you have the culprit, show me how youre initialicing the systick

we dont need to firmware by ourselves, lets talk