Hi. I’m trying to lower my MCU current consumption by putting MCU in Sleep mode. therefore I Tried to implement TICKLESS_IDLE mode in my project. My MCU is stm32L4 Family and my FREERTOS version is 10.2.1 and timebase is SysTick.
In baremetal application it’s possible to lower clock frequency before call WFI instruction and after exiting sleep mode, increase the clock frequency and in this case everything goes well.
By implementing “TICKLESS_IDLE” my MCU current consumption is decreased. But I want to lower it more.
I did this, in FreeRTOS by reducing CLK frequency in “PreSleepProcessing” hook and then turn back CLK frequency to its main value in PostSleepProcessing. Moreover I put *ulExpectedIdleTime = 0 to avoid OS calls WFI instruction and I call this instruction myself.
In this case, I’ve realized that OS timing goes wrong and application will be corrupted.
My questions is, what should I do to avoid this problem? Is there any solution to solve this problem?
Thanks in advance.
If you are slowing the clock that is used to bring the system out of low power mode then the amount of time you spend in low power mode will have to be calculated at the lower clock speed. By default the tickless idle will calculate it at whatever the speed is set to in FreeRTOSConfig.h.
Do you have to use the SysTick? This example generates the tick from the TIM2 peripheral. https://www.freertos.org/STM32L-discovery-low-power-tickless-RTOS-demo.html
One solution with that line of processors is to switch the Tick Timer to one of the Low Power Timers that run off the 32768 Hz crystal, so that changing the processor clock doesn’t affect the speed of the timer. This will have the slight disadvantage that your tick rate isn’t an exact round number of milliseconds.
A second option is to use one of the timer peripherals (instead of the core systick timer that is the default) and run it off a clock other than the processor so it doesn’t change rate when you change the processor clock.
Thank You for your answer.
if I understand correctly, the problem is that I’ve changed the CLK speed but TICK timer is still calculated by previous CLK value. is that correct?
Q1) is there any solution to still use SysTick as timebase? for example update the TICK RATE as a variable not macro (configTICK_RATE_HZ) ?
Q2) Does configCPU_CLOCK_HZ play role in this matter?
No, because the time at which tasks need to unblock has already been calculated with the original clock speed. You can use SysTick for the normal tick interrupt, then turn SysTick off and use a different clock when you enter low power state, but that will require you to create a custom implementation (which the system lets you do, as per the link I sent before). If you want to enter a deep sleep you need to turn the SysTick clock off anyway, again as demonstrated on the link in my previous post.
Hi Mohsen, if you have an LPTIM available, you can use lptimTick.c to provide the tick. You can choose to clock LPTIM with LSE or LSI. The code provides a precise tick frequency, even 1000Hz from 32768Hz. It’s compatible with your clock-speed-reduction strategy. For even further reduction in power consumption, it’s compatible with STOP modes too.