periph_clk_en on STM32L with -Os optimization may result in Hard Fault

Hi everyone

While working with low-power modes on STM32L1, we found a bug (?) in gcc with -Os optimization - somehow it “optimizes” rather simple periph_clk_en(bus_t bus, uint32_t mask) function in cpu/stm32_common/cpu_common.c, so using it right after waking up from STOP mode results in Hard Fault (for some reasons, in our firmware it is called from clk_init(), and clk_init() is called right after __WFI() in LPM code, as we need to switch MCU from 2 MHz MSI clock back to our default clock settings).

Didn’t dig it any deeper yet, but just for everyone to know:

-void periph_clk_en(bus_t bus, uint32_t mask)

+void attribute((optimize(“O3”))) periph_clk_en(bus_t bus, uint32_t mask)

fixes it.


I also had a problem when waking up from stop mode (stm32f091) if openocd is used to start the board. The code works perfectly if I restart the power supply but with ‘make reset’ it fails to reconfigure the clock after leaving stop mode. (the code continues to run but with the wrong clock)

It seems the value of r1 is lost in stop mode when openocd was used to restart the board. Adding __ISB() after __WFI() solved it for me. This was on a stm32f0 with pm_layered