cancel
Showing results for 
Search instead for 
Did you mean: 

Flash bank swap on STM32L471ZG - how BFB2 and FB_MODE works?

Gergo Santha
Associate II

Hi!

We are working on a remote FW update feature, where we receive the FW binary from another MCU via UART4 in chunks. The process starts with erasing a region in flash bank 2 (page 256 - 406). Then it receives the FW image in 2K chunks, CRC checks them and flashes them. Finally, it CRC checks the entire new FW in the flash memory. If everything is fine it will:

uint32_t usedBank = LL_SYSCFG_GetFlashBankMode();

if (HAL_FLASH_Unlock() != HAL_OK) {
		consoleLog(LOG_INFO, "The HAL_FLASH_Unlock process failed!");
		return FirmwareUpdateResultCode::flashLockUnlockError;
	}
	if (HAL_FLASH_OB_Unlock() != HAL_OK) {
		consoleLog(LOG_ERROR, "The HAL_FLASH_OB_Unlock process failed!");
		return FirmwareUpdateResultCode::flashOBLockUnlockError;
	}
 
	consoleLog(LOG_DEBUG, "Firmware update data content uploaded successfully.");
	rtosTaskDelayInMilisec(500);
 
	FLASH_OBProgramInitTypeDef optionBytesStruct;
	HAL_FLASHEx_OBGetConfig(&optionBytesStruct);
	optionBytesStruct.OptionType = OPTIONBYTE_USER;
	optionBytesStruct.USERType = OB_USER_BFB2;
	if (usedBank == LL_SYSCFG_BANKMODE_BANK1) {
		optionBytesStruct.USERConfig = OB_BFB2_ENABLE;
	} else {
		optionBytesStruct.USERConfig = OB_BFB2_DISABLE;
	}
	
 
	if (HAL_FLASHEx_OBProgram(&optionBytesStruct) != HAL_OK) {
		consoleLog(LOG_ERROR, "The HAL_FLASHEx_OBProgram process failed!");
		return FirmwareUpdateResultCode::flashOBProgramError;
	}
 
	HAL_FLASHEx_OBGetConfig(&optionBytesStruct);
	consoleLog(LOG_DEBUG, "FLASH_OPTR: %08x", optionBytesStruct.USERConfig);
 
	if (HAL_FLASH_OB_Launch() != HAL_OK) {
		consoleLog(LOG_ERROR, "The HAL_FLASH_OB_Launch process failed!");
		return FirmwareUpdateResultCode::flashOBLaunchError;
	}
 
	// _noreturn and reset automatically if BFB2 update is successfully
 
	if (HAL_FLASH_OB_Lock() != HAL_OK) {
		consoleLog(LOG_ERROR, "The HAL_FLASH_OB_Lock process failed");
		return FirmwareUpdateResultCode::flashOBLockUnlockError;
	}
	if (HAL_FLASH_Lock() != HAL_OK) {
		consoleLog(LOG_ERROR, "The HAL_FLASH_Lock process failed!");
		return FirmwareUpdateResultCode::flashLockUnlockError;
	}
 
	return FirmwareUpdateResultCode::bfb2UpdateError;

We have 2 almost identical FW binaries (size around ~240k), the only difference is in the startup print: 'Image A' or 'Image B'. The process seems to work fine as we are able to download the other FW binary and restart the MCU. We can observe the alternating 'Image A' and 'Image B' printouts. So far so good.

However, we would like to know which bank we are actually in and we would like to implement a fall-back feature as well to the previous binary in case the new FW producing erratic behaviour. So we started to check the values of SYSCFG->MEMRMP and FLASH_OPTR on startup. Strangely we have the following results:

  • SYSCFG->MEMRMP is always zero no matter which FW binary is running
  • when setting BFB2 bit in option bytes the readout is 0xFFFFF800 which is okay so we call HAL_FLASH_OB_Launch to restart the MCU
  • reading FLASH_OPTR (either using HAL or directly by *(uint32_t *)0x1fff7800) the value is ALWAYS 0xFFEFF800 (HAL) or 0xFFEFF8AA (direct) no matter which binary is running

Basically we - seems to - have a working update mechanism but we don't understand the behaviour SYSCFG->MEMRMP and FLASH_OPTR BFB2.

At this point we are not using any debugger or programmer, only a python script which is sending the chunks via an USB-UART converter connected to the STM32.

Any help will be great and appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions
FBL
ST Employee

Hello @Gergo Santha​ 

I suggest check this post BFB2 and bootloader flash-bank selection (st.com). Overall, when BFB2 bit is set and the boot pins are in the boot from main Flash memory configuration, the device boots from system memory, and the bootloader jumps to execute the user application programmed in Flash memory bank 2. From Flash's point of view, the system memory remains aliased at @0x0000 0000.

Also, you can find out more details in AN2606 section 66.1.2 Bootloader selection.

Hope this helps you to understand the behavior!

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

3 REPLIES 3
FBL
ST Employee

Hello @Gergo Santha​ 

I suggest check this post BFB2 and bootloader flash-bank selection (st.com). Overall, when BFB2 bit is set and the boot pins are in the boot from main Flash memory configuration, the device boots from system memory, and the bootloader jumps to execute the user application programmed in Flash memory bank 2. From Flash's point of view, the system memory remains aliased at @0x0000 0000.

Also, you can find out more details in AN2606 section 66.1.2 Bootloader selection.

Hope this helps you to understand the behavior!

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Gergo Santha
Associate II

Hi

FInally we were able to solve this problem: it was banal as usual, there was an unnoticed function which changed to Bank 1 after startup.

Hi again @Gergo Santha​, thank you for your feedback.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.