cancel
Showing results for 
Search instead for 
Did you mean: 

Invalid reset cause after jumping from bootloader

SP.3
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions
berendi
Principal

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.

View solution in original post

8 REPLIES 8

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.

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.

>>>> 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.

berendi
Principal

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.

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.

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

SP.3
Associate II

Is it not recommended to De-initialize the clocks and peripherals before jumping to application?

Currently, it is de-initialized in Boot before jumping and initialized again in application.

The application startup code deinitializes the clocks in in SystemInit() too, so you are doing it twice. No harm in it, but removing HAL_RCC_DeInit() might be the simplest solution to your problem.