cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5 series bank swap not working

HParsons
Associate

First post, please let me know if I've made any mistakes in asking my question.

I'm trying to write a bootloader for a device using a STM32u585ZIT chip. When booting, it will read a partition table saved in flash to determine if it will boot from partition A (Address 0x08080000) or partition B (Address 0x08180000). I have decided on using the BANK_SWAP option byte to swap the addresses of these partitions so that I only need to write a single linker script for the application code. 

Here is the code I'm using to set the swap bit if we want to boot from partition B: 

if ((partitions.a == partitionStatusUpdate)
			|| ((partitions.a == partitionStatusActive)
					&& (partitions.b != partitionStatusUpdate))) {
		printf("Booting partition A\n");
	} else if ((partitions.b == partitionStatusUpdate)
			|| ((partitions.b == partitionStatusActive)
					&& (partitions.a != partitionStatusUpdate))) {
		if (HAL_FLASH_Unlock() != HAL_OK) {
			printf("Could not unlock flash!\n");
			NVIC_SystemReset();
		}
		if (HAL_FLASH_OB_Unlock() != HAL_OK) {
			printf("Could not unlock flash option bytes!\n");
			NVIC_SystemReset();
		}
		FLASH->OPTR |= FLASH_OPTR_SWAP_BANK;
		if (HAL_FLASH_OB_Lock() != HAL_OK) {
			printf("Could not lock flash!\n");
			NVIC_SystemReset();
		}
		if (HAL_FLASH_Lock() != HAL_OK) {
			printf("Could not lock flash option bytes!\n");
			NVIC_SystemReset();
		}
	}

 From what I gather from reference documents this should swap the banks' addresses, so I should only ever need to tell it to access the application at 0x08080000 after this point. However, using the following code (APP_ACTIVE_ADDR == 0x08080000):

appAddress = (uint32_t*) APP_ACTIVE_ADDR + 1;
GoToApplication = (pFunction) *appAddress;
__set_MSP(*(uint32_t*) APP_ACTIVE_ADDR);
SCB->VTOR = APP_ACTIVE_ADDR;
GoToApplication();

I am finding it only ever boots app A. 

I have searched around and found people asking similar questions regarding different chips, but the only question referring to the U5 specifically is this one, but I don't think the answer there is relevant to me because the original poster was using two separate linker scripts:

https://community.st.com/t5/stm32cubeprogrammer-mcus/mb1549c-swapbank-is-set-1-but-its-not-run-bank2-firmware-always/td-p/57235 

I assume I am missing some steps to make this work, but I cannot figure out what they are. Can anyone help? Please let me know if any extra information is required or if I have been unclear about anything.

1 REPLY 1
FBL
ST Employee

Hi @HParsons 

I guess you are missing OB launch loading. In fact, after setting the BANK_SWAP option byte, a system reset is usually required for the changes to take effect. Ensure that you are performing a system reset after programming the option bytes HAL_FLASH_OB_Launch(); An example is provided in Cube Firmware. It should be helpful.

STM32CubeU5/Projects/NUCLEO-U575ZI-Q/Examples/FLASH/FLASH_SwapBanks at main · STMicroelectronics/STM32CubeU5 (github.com)

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.