2025-11-25 8:00 PM
Hello everyone!
I'm facing a problem when trying to switch a bank on STM32H745 MCU. The issue happens only when the debugger is disconnected. Our implementation uses the HAL library to perform Bank switch like this:
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
FLASH_OBProgramInitTypeDef info;
HAL_FLASHEx_OBGetConfig(&info);
// swap banks in option bytes
info.OptionType = OPTIONBYTE_USER;
info.USERType = OB_USER_SWAP_BANK;
if (info.USERConfig & OB_SWAP_BANK_ENABLE)
info.USERConfig &= ~OB_SWAP_BANK_ENABLE;
else
info.USERConfig |= OB_SWAP_BANK_ENABLE;
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK2);
HAL_StatusTypeDef ret = HAL_FLASHEx_OBProgram(&info);
if (HAL_OK == ret)
{
// launch new configuration
ret = HAL_FLASH_OB_Launch();
}
(void)HAL_FLASH_OB_Lock();
(void)HAL_FLASH_Lock();
__HAL_RCC_CLEAR_RESET_FLAGS();
NVIC_SystemReset();In some of the builds it does not work and after reset it keeps running the previous image.
I found that
2025-11-26 6:25 AM
Here are the reasons PGSERR is set:
I don't see any of those conditions being caused be the code posted, so the problem is likely elsewhere. Are you writing to flash, perhaps?
2025-12-02 12:24 AM
Not in the same power cycle. We implemented the logic to verify if the current bank contains a stable image, and if not it should switch the bank to the second one. However, it does not work because of this PGSERR. I'm not able to catch where exactly this flag is set because the problem is not reproducible with the debugger connected. An was able to catch the problem only by putting an infinite loop in
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
{
/* Wait for the FLASH operation to complete by polling on QW flag to be reset.
Even if the FLASH operation fails, the QW flag will be reset and an error
flag will be set */
uint32_t bsyflag = FLASH_FLAG_QW_BANK1;
uint32_t errorflag = 0;
uint32_t tickstart = HAL_GetTick();
assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
#if defined (DUAL_BANK)
if (Bank == FLASH_BANK_2)
{
/* Select bsyflag depending on Bank */
bsyflag = FLASH_FLAG_QW_BANK2;
}
#endif /* DUAL_BANK */
while (__HAL_FLASH_GET_FLAG(bsyflag))
{
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
{
return HAL_TIMEOUT;
}
}
HAL_FLASH_WaitForLastOperationCallback();
}
/* Get Error Flags */
if (Bank == FLASH_BANK_1)
{
errorflag = FLASH->SR1 & FLASH_FLAG_ALL_ERRORS_BANK1;
}
#if defined (DUAL_BANK)
else
{
errorflag = (FLASH->SR2 & FLASH_FLAG_ALL_ERRORS_BANK2) | 0x80000000U;
}
#endif /* DUAL_BANK */
/* In case of error reported in Flash SR1 or SR2 register */
if((errorflag & 0x7FFFFFFFU) != 0U)
{
/*Save the error code*/
pFlash.ErrorCode |= errorflag;
while(1);
/* Clear error programming flags */
__HAL_FLASH_CLEAR_FLAG(errorflag);
return HAL_ERROR;
}The problem seems to be occuring only when trying to switch the banks without writing any data to flash. We have another logic to update banks data and switch it and it works completely fine.
2025-12-02 6:16 AM
These are hardware state machines and not prone to spontaneous behavior. I would look for a bug related to your flash write routines.
Instrument code with a UART debug stream or other output so that you can instrument the code and view what is happening without the debugger attached.