2023-01-11 05: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 05: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 05: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 05: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 06: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 06:05 AM
No, I am calling JumpToApplication from main().
2023-01-11 06:07 AM
somthing fishy is going on with your systick
2023-01-11 06:07 AM
place a HAL_Delay(100): in main does it fail also?
2023-01-11 06:23 AM
Yes, It does
2023-01-11 06:23 AM
there you have the culprit, show me how youre initialicing the systick