What does SystemInit() typically do, and why does it run before main()?
SystemInit() is a C function (defined by CMSIS convention in system_stm32f4xx.c or the equivalent for your MCU family) that configures the core chip-level settings needed before any application code can run reliably. Its primary responsibilities are: (1) configuring the clock tree — enabling the HSE oscillator, configuring the PLL multipliers and dividers to achieve the target system clock frequency, switching SYSCLK to the PLL output, and setting AHB/APB prescalers; (2) setting Flash wait states to match the new clock speed — if the CPU runs at 168 MHz but Flash is still configured for 16 MHz (the reset default), instruction fetches will return corrupt data and the processor will hard fault; (3) optionally enabling the FPU (on Cortex-M4F/M7 with hardware floating point) by setting the CP10/CP11 bits in the CPACR register — without this, any floating-point instruction triggers a UsageFault.
SystemInit() runs after the .data copy and .bss zeroing in the startup code but before main(). This ordering matters because SystemInit() is a C function that may use global variables (which must be initialized first), and because main() typically expects the clock to be running at full speed before configuring peripherals — UART baud rate calculations, timer prescaler values, and SPI clock dividers all depend on knowing the actual system clock frequency. If SystemInit() ran after main() started configuring peripherals, all timing-sensitive configurations would be wrong.
A common debugging scenario: the MCU hard faults immediately after reset before reaching main(). The most likely cause is a SystemInit() that configures an HSE crystal oscillator that is not populated on the board, causing the PLL to never lock and the clock switch to fail. Another common issue is configuring the wrong Flash wait states for the target frequency — zero wait states at 168 MHz will corrupt every instruction fetch. Always verify that SystemInit() matches your actual hardware configuration, not just the evaluation board defaults.
Source: Boot & Startup Q&A
