The common denominator of these problems is the built-in bootloader; however, there are several mechanisms involved.
The built-in bootloader is located to the so called system memory - an area of FLASH at 0x1FFFxxxx addresses, which is programmed at factory and locked, so that it can't be reprogrammed. When the entry mechanism is activated at mcu reset, this memory is mapped (aliased) by hardware at 0x0000'0000, from where the processor boots. The bootloader entry mechanisms for individual STM32 (sub)families differ, and they (together with other details) are described in AN2606.
If the user program after programming it into FLASH and subsequent reset, does not work, it may be that:
- the BOOT0 pin is left floating - this is a high-impedance input, which may inadvertently get pulled up e.g. through resistance of soldering residui.
- in some newer STM32 models, BOOT0 pin is shared with a GPIO. In this case, the pin is sampled at reset, and if samples as 1, it enters bootloader; else the user program can use it as GPIO. If this feature is not disabled in Option bytes, user has to make sure the pin reads as 0 at reset (e.g. using a suitable pulldown). If this pin is used as input, the connected device must not pull it down during reset. Note, that even in case this pin is used as output, parasitic capacitances may "hold" an unwanted high level long enough to be sampled at the end of a potentially short reset pulse (e.g. internal reset sources such as watchdog or software reset result in a min. 20us reset pulse).
- in some STM32, if previous power-on reset was accomplished while FLASH was empty, the PEMPTY bit keeps entering bootloader upon subsequent resets until a power cycle or executing option-byte reload (OBL_LAUNCH).
- in some STM32 models with dual-bank FLASH (e.g. 'G4 cat.3, or the high-end L4 and L4+), if booting from the second bank is enabled in Option bytes (by setting BLB2 bit), the System memory is mapped at 0x0000'0000 even if program executes from user FLASH after reset. If in that case user leaves the SCB_VTOR register at its reset (zeroed) state, interrupts will be executed according to the vector table in system memory i.e. from the bootloader, often resulting in crash - which ends up in HardFault handler again in the system memory, i.e. at a 0x1FFFxxxx address.
Common remedy to BOOT0-pin-related problems is to set the Option bytes so, that the hardware pin is not sampled at startup, effectively disabling the bootloader entirely.
In cases where the system memory (bootloader area) remains mapped at 0x0000'0000, before enabling any interrupt, the SCB_VTOR register has to be set to 0x0800'0000 to map properly the vector table to user FLASH. Alternatively, (e.g. in 'F0 based on Cortex-M0 which does not have SCB_VTOR), use the remapping mechanism (usually a MEM_MODE field in some of the SYSCFG registers) to map user FLASH to 0x0000'0000.