STM32H7A3,Trying to change CPU clock dynamically without affecting peripherals
Hi all,
It is embarrassing when the browser crash when writing long text...
Here is the original thought:
I am trying to implement some low power in my MCU but not looking for extreme standby mode. I first try to stop CPU but it doesnt save too much power because the AXI are still running at high frequency. Then I try this, a dynamic CPU clock (possibly with AXI memory clock).
From the clock tree, I can see there are 2 registers to control the clock to CPU and most of the peripherals. My goal is to change the CPU clock without affecting the peripherals clock.
I am using an RTOS so I can easily know when to enter idle thread (task) (reduced CPU clock) or user thread (high CPU clock). I implement the below codes to switch between high and low clocks. These code are called bay RTOS's scheduler, when it switch to idle, call low_performance, when it switch to user threads, call the other.
static inline void cpu_high_performance()
{
LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_8);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
}
static inline void cpu_low_power()
{
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_1);
LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_8);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
After a few trials, the MCU is sucessfuly running with 200M/25M now.
But I still have many concerns about this method.
- Whether the register is designed to be changed so frequently? RTOS can switch thousands of times in a second.
- There is a gap between changing 2 registers (while one changed the other doesn't.) It will introduce a spike in the peripheral clock. I am not too worried about spi/i2c etc, but UART might be the case?
I did meet some problems during trials, such as the OPSI clock being too high (200M) which the CPU being only 25M, the whole system stop working (cannot even enter hard fault or download firmware). Another problem is the clock in interrupt will sometimes be the low frequency 25M, but it seems ok. If it doesn't, I can still implement the clock change in the interrupt.
The power saving result is quite significant, I save 50% of power consumption with the dynamic clock compared to 200M while my system load is only 20%.
My problems are, whether this method is correct? What are the other possible issues?
Thanks.
