Why might setting BFB2 cause printf to stop working?
I've written a fairly simple test case for using the system bootloader to boot from flash bank 2 on a STM32F429ZIT6U (developing on a Nucleo F429ZI board). With stdio redirected to a UART, I'm able to direct the code to:
- Mass-Erase Bank 2
- Copy the entirety of Bank 1 to Bank 2
- Set the BFB2 bit
The function that sets BFB2 looks like this:
void boot_bank_select(uint8_t bank_bit) {
FLASH_AdvOBProgramInitTypeDef optionbits = {
.OptionType = OPTIONBYTE_BOOTCONFIG,
.BootConfig = (bank_bit) ? OB_DUAL_BOOT_ENABLE : OB_DUAL_BOOT_DISABLE
};
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_AdvOBProgram(&optionbits);
printf("Waiting for option bit write...\r\n");
HAL_StatusTypeDef rc = HAL_FLASH_OB_Launch();
if(rc == HAL_OK)
printf("Bank select completed.\r\n");
else
printf("Bank select failed.\r\n");
}By placing a few strategic breakpoints, I can see that once the option bit write takes place, printf starts causing an endless reboot cycle. Code in main() executes up to the first place printf() is called, then it reboots.
Looking at disassembly, I can see a point where a "bx lr" jumps into the middle of the boilerplate startup code, so I don't think an actual fault or reset is occuring; it's more likely a case of stack corruption. However, the situation persists through hard resets; I can only regain control of the chip by using STProg to clear the BFB2 option bit.
I'm at a loss. Bank 2 is identical to Bank 1; I know this because the code itself copies it directly, and I can download and compare the two banks via STProg and see that they're identical. So why would having the bank switched cause the code to jump to strange places?
I can provide all of the code if necessary.
