Small update, HAL has received a new API to switch clock/power configurations at runtime: halClockSwitchMode()
Configurations are encoded in structures, two configurations are pre-defined:
- hal_clkcfg_reset, which restores a post-reset state, this can be used to de-initialize clocks, for example from a bootloader before jumping the in application code.
- hal_clkcfg_default, which programs the settings in halconf.h (this is performed implicitly on halInit() in order to keep exactly the current behaviour).
Of course it is possible to define multiple configurations and switch those on the fly. The API checks the configuration first then applies it, the function can fail (returning true) if the configuration is not correct (this will probably be changed in assertions, it is a dev time error) or if cannot be applied (HW timeouts, unexpected conditions and similar).
Another function halGetClockPoint() allows to read the current frequency on all relevant points of the clock tree, for example SYSCLK, PCLKx, PLLVCO etc etc
HAL drivers read the frequency on xxxStart(), so if you switch clocks you need to stop and restart the drivers affected, for example the serial driver can recalculate the baud rate divider based on the new clock settings.
The new API is already implemented on STM32G4, STM32L4+ and STM32WL, more will follow but, probably, not the older ones. There is also an mcuconf.h settings to disable the new API and restore the old static initialization.