2018-08-13 05:00 PM
Ok just trying to get the bank swapping working.
Loaded and flashed new firmware in to 0x08100000 all goes fine, all i need to do is to swap the flash banks.
Now the code below does do the bank swap fine, but it gets stuck at the HAL_FLASH_OB_Launch();
Does not hard fault, but does not get past it either, the cpu just seems to stop??
If i then press reset button on the board, the bank swap does complete and all is well,
I thought the HAL_FLASH_OB_Launch(); was supposed to reset the cpu?
If not why does it not get any further than that function?
I do have a workaround, by setting the watchdog timer, but would like to know whats going on?
Im using STM32Cube_FW_H7_V1.3.0
HAL_FLASH_OB_Unlock();
/* Get FLASH_WRP_SECTORS write protection status */
//OBInit.Banks = FLASH_BANK_1;
HAL_FLASHEx_OBGetConfig(&OBInit);
/* Check Swap Flash banks status */
if ((OBInit.USERConfig & OB_SWAP_BANK_ENABLE) == OB_SWAP_BANK_DISABLE)
{
/*Swap to bank2 */
/*Set OB SWAP_BANK_OPT to swap Bank2*/
printf("Swapping to bank2\r\n");
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_SWAP_BANK;
OBInit.USERConfig = OB_SWAP_BANK_ENABLE;
HAL_FLASHEx_OBProgram(&OBInit);
printf("Launch\r\n");
/* Launch Option bytes loading */
HAL_FLASH_OB_Launch();
printf("DONE Restarting\r\n");
/*
as the CPU is executing from the Flash Bank1, and the I-Cache is enabled :
Instruction cache must be invalidated after bank switching to ensure that
CPU will fetch correct instructions from the flash.
*/
SCB_InvalidateICache();
HAL_NVIC_SystemReset();
}
else
{
/* Swap to bank1 */
/*Set OB SWAP_BANK_OPT to swap Bank1*/
printf("Swapping to bank1\r\n");
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_SWAP_BANK;
OBInit.USERConfig = OB_SWAP_BANK_DISABLE;
HAL_FLASHEx_OBProgram(&OBInit);
printf("Launch\r\n");
/* Launch Option bytes loading */
HAL_FLASH_OB_Launch();
printf("DONE Restarting\r\n");
/*
as the CPU is executing from the Flash Bank1, and the I-Cache is enabled :
Instruction cache must be invalidated after bank switching to ensure that
CPU will fetch correct instructions from the flash.
*/
SCB_InvalidateICache();
HAL_NVIC_SystemReset();
}
2018-08-23 09:31 AM
We too are having problems in the bank switch; but we are using STM32F429.
This used to work fine for us but we switched from IWDG to WWDG at some point.
We switch bank at the HAL_FLASH_OB_Launch() fine if we disable using WWDG; but if watchdog is enabled its like we hang in that call; our HW Watchdog does not seem to restart the board.
If we than use ST-Link to read the option bytes its like all sectors are read protected.
2019-01-15 12:40 AM
I fixed this problem by moving the soft reset up before invalidating the I cache
HAL_FLASH_OB_Launch();
HAL_NVIC_SystemReset();
SCB_InvalidateICache();
2019-09-25 06:12 AM
Hello,
have basically the same problem with a Stm32h743 in ! V revision !
The program stucks if option byte is switched from bank 2 to bank 1... also debugger access is lost...
After power cycling the bank is successful selected and runs.
Any new thinks here?
My workflow:
Some comments to the other comments:
2019-09-25 12:54 PM
> Have basically the same problem with a Stm32h743 in ! V revision !
See AN5312 Migration from Rev Y to rev V, page 6: "It is not possible to swap banks on the fly".
-- pa
2019-09-25 10:30 PM
Ah, the above source codes tries to swap the banks on the fly... that's why clearing the instruction cash is required.
I get it... But it's not my use case. I just want to set swap banks and wait for the user until power cycle or (reboot -> NVIC_SystemReset).
Here are the source, with a lot of maybe non req. safety checks -> wait for last ob operation... etc.
int flashoper_swapbanks(uint32_t crc_value)
{
//if crc of flash firmware matches with the given crc in the file header
if(!flashoper_crccheck(crc_value, curr_programming_addr))
{
return 0;
}
logging_debug(LOGMOD_FWUPDATE, "Start swap bank process from bank %u to bank %u", flashoper_getactbank(), (flashoper_getactbank() == 1) ? 2 : 1);
vTaskDelay(10);
if(HAL_GetREVID() == 0x1003)
{
//Y device does not support error free bank swapping
logging_error(LOGMOD_FWUPDATE, "Bank swapping unsupported on this device");
vTaskDelay(50);
assert_param(0);
return 0;
/*2.2.8 Flash memory bank swapping might impact embedded
Flash memory interface behavior
Description
When Flash memory bank swapping feature is enabled, the embedded Flash memory interface behavior might become unpredictable.
Workaround
Do not enable the Flash memory bank swapping feature on devices revision Y.
*/
}
logging_debug(LOGMOD_FWUPDATE, "hier 1");
vTaskDelay(10);
HAL_FLASH_OB_Unlock();
logging_debug(LOGMOD_FWUPDATE, "hier 2");
vTaskDelay(10);
int bank = flashoper_getactbank();
if(bank == 1)
SET_BIT(FLASH->OPTSR_PRG, FLASH_OPTCR_SWAP_BANK);
else
CLEAR_BIT(FLASH->OPTSR_PRG, FLASH_OPTCR_SWAP_BANK);
logging_debug(LOGMOD_FWUPDATE, "hier 3 0x%08X", FLASH->OPTSR_PRG);
vTaskDelay(10);
int timeout = FLASHOPERATIONS_FLASHOPERTIMEOUT; //ms
//wait until option byte flash is ready -> blocking!
while(FLASH_OB_WaitForLastOperation(0) != HAL_OK)
{
logging_debug(LOGMOD_FWUPDATE, "hier 4 0x%08X", FLASH->OPTSR_CUR);
if(timeout-- <= 0)
{
HAL_FLASH_OB_Lock();
logging_error(LOGMOD_FWUPDATE, "Option bytes not ready");
return 0;
}
vTaskDelay(1);
}
logging_debug(LOGMOD_FWUPDATE, "hier 5");
vTaskDelay(10);
//start writing option bit
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
logging_debug(LOGMOD_FWUPDATE, "hier 6 0x%08X", FLASH->OPTCR);
vTaskDelay(10);
//wait until option byte is set
timeout = FLASHOPERATIONS_FLASHOPERTIMEOUT;
if(bank == 1)
{
while(HAL_IS_BIT_CLR(FLASH->OPTSR_CUR, FLASH_OPTSR_SWAP_BANK_OPT))
{
logging_debug(LOGMOD_FWUPDATE, "hier 7");
if(timeout-- <= 0)
{
HAL_FLASH_OB_Lock();
logging_error(LOGMOD_FWUPDATE, "Option byte set from bank 1 fails");
return 0;
}
vTaskDelay(1);
}
}
else
{
while(HAL_IS_BIT_SET(FLASH->OPTSR_CUR, FLASH_OPTSR_SWAP_BANK_OPT))
{
logging_debug(LOGMOD_FWUPDATE, "hier 8");
if(timeout-- <= 0)
{
HAL_FLASH_OB_Lock();
logging_error(LOGMOD_FWUPDATE, "Option byte set from bank 2 fails");
return 0;
}
vTaskDelay(1);
}
}
logging_debug(LOGMOD_FWUPDATE, "hier 9 0x%08X", FLASH->OPTSR_CUR);
vTaskDelay(10);
timeout = FLASHOPERATIONS_FLASHOPERTIMEOUT; //ms
//wait until option byte flash is ready -> blocking!
while(FLASH_OB_WaitForLastOperation(0) != HAL_OK)
{
logging_debug(LOGMOD_FWUPDATE, "hier 10");
if(timeout-- <= 0)
{
HAL_FLASH_OB_Lock();
logging_error(LOGMOD_FWUPDATE, "Option bytes not ready");
return 0;
}
vTaskDelay(1);
}
logging_debug(LOGMOD_FWUPDATE, "hier 11");
HAL_FLASH_OB_Lock();
logging_debug(LOGMOD_FWUPDATE, "hier 12");
return 1;
}
Output:
Start swap bank process from bank 1 to bank 2
hier 1
hier 2
hier 3 0x8BC6AAF0
hier 5
hier 6 0x00000000
hier 9 0x8BC6AAF0
hier 11
hier 12
$
......
Start swap bank process from bank 2 to bank 1
hier 1
hier 2
hier 3 0x0BC6AAF0
hier 5
hier 6 0x80000000
The process stuck's on "hier 6" if bank 2 to bank 1 swap is req.
2019-09-30 02:05 AM
Okay, got it!
The calibration values for the internal temperature measurement used with the marcro: __HAL_ADC_CALC_TEMPERATURE are stored on flash bank 1 (System Flash memory 0x1FF0 0000 - 0x1FF1 FFFF). If the erase of flash bank 1 is ongoing the program (all tasks) stalls even if you have two banks and the program works an bank 2.
Also the reading from flash bank 1 (__HAL_ADC_CALC_TEMPERATURE ) will perhaps crash the option byte programming (FLASH_OB_WaitForLastOperation) in an RTOS environment.