Skip to main content
Visitor II
December 5, 2019
Solved

Invalid reset cause after jumping from bootloader

  • December 5, 2019
  • 2 replies
  • 2419 views

Hello Team,

I am using STM32F767ZI Nucleo board in my project.

Bootloader flash start address - 0x08000000

Bootloader to application jump address - 0x08020200

Application flash start address - 0x08020000

Read reset cause snippet:

 if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))
 {
 reset_cause = RESET_CAUSE_INDEPENDENT_WATCHDOG_RESET;
 }
 else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST))
 {
 reset_cause = RESET_CAUSE_SOFTWARE_RESET;
 }
 else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST))
 {
 reset_cause = RESET_CAUSE_POWER_ON_POWER_DOWN_RESET;
 }
 else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
 {
 reset_cause = RESET_CAUSE_EXTERNAL_RESET_PIN_RESET;
 }
 else if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
 {
 reset_cause = RESET_CAUSE_BROWNOUT_RESET;
 }
 else
 {
 reset_cause = RESET_CAUSE_UNKNOWN;
 }

Clear reset cause snippet:

__HAL_RCC_CLEAR_RESET_FLAGS();

Jump to application snippet:

 typedef void (*pFunction)(void);
 
 HAL_RCC_DeInit();
 HAL_DeInit();
 HAL_MPU_Disable();
 
 uint32_t bootAddress = UINT32_C(0x08020200);
 pFunction jumpToAddress;
 
 uint32_t JumpAddress = *(uint32_t *) (bootAddress + 4);
 jumpToAddress = (pFunction) JumpAddress;
 
 /* Reset System Ticks*/
 SysTick->CTRL = 0;
 SysTick->LOAD = 0;
 SysTick->VAL = 0;
 
 /* Reallocate vector table */
 SCB->VTOR = bootAddress;
 
 /* Initialize user application's Stack Pointer */
 __set_MSP(*(__IO uint32_t*) bootAddress);
 
 jumpToAddress();

When the reset cause is read in bootloader, I get valid values.

In the similar way, when i read in the application instead of boot loader, I always get RESET_CAUSE_UNKNOWN for any type of reset.

Note : Always the register is cleared after reading.

Is the jumping operation affecting the RCC_CSR register somehow ?

Any clue regarding this behavior would be of great help.

    This topic has been closed for replies.
    Best answer by berendi

    The flags don't clear themselves, and your code doesn't clear them either. Then there must be some library function called in your program that clears it, with or without reason.

    And yes, HAL_RCC_DeInit() clears it. No idea why, maybe the developer was paid by line.

    2 replies

    Visitor II
    December 5, 2019

    Hi. Maybe because jumping to main application don`t causes any resets. If in your main application appear any resets, microcontroller set program counter to 0x08000000. So program execution starts from bootloader.

    SP.3Author
    Visitor II
    December 5, 2019

    Hi,

    Yes, there is no reset while jumping form bootlaoder to application.

    But my expectation is that, since the reset cause register is not read in bootlaoder, the values must be retained while reading in application.

    Visitor II
    December 5, 2019

    >>>> Note : Always the register is cleared after reading.

    Do you clear reset flags in bootloader?

    I'v tested reading of reset causes in my bootloader and main app. All work fine.

    berendiAnswer
    Visitor II
    December 5, 2019

    The flags don't clear themselves, and your code doesn't clear them either. Then there must be some library function called in your program that clears it, with or without reason.

    And yes, HAL_RCC_DeInit() clears it. No idea why, maybe the developer was paid by line.

    SP.3Author
    Visitor II
    December 5, 2019

    Thanks for your inputs.

    Yes. I also found now that it is being cleared in HAL_RCC_DeInit() API.

    Will think of a way to persist this info and make use of this in application also.

    Visitor II
    December 5, 2019

    Just don't call HAL_RCC_DeInit(). This function makes no sense at all there.