2023-01-11 5:37 AM
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.
2023-01-11 5:51 AM
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
2023-01-11 5:55 AM
Hi @Javier Muñoz ,
I am using also almost the same functions, but calling the HAL_RCC_DeInit() goes wrong, jumps to HardFault_Handler().
2023-01-11 5:57 AM
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.
2023-01-11 6:03 AM
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
2023-01-11 6:05 AM
No, I am calling JumpToApplication from main().
2023-01-11 6:07 AM
somthing fishy is going on with your systick
2023-01-11 6:07 AM
place a HAL_Delay(100): in main does it fail also?
2023-01-11 6:23 AM
Yes, It does
2023-01-11 6:23 AM
there you have the culprit, show me how youre initialicing the systick