Stop2 mode implementation in freertos idle task in stm32

Hi i am using freertos tickless mode in stm32(by setting the TICKLESS_IDLE to 1). and then in the PreSleepProcessing function i just suspend the hal tick and go into the stop 2 mode. But while debugging I found out the stop 2 mode is not functioning. Like the code is getting executed the moment I step over, it is not waiting for an interrupt. How can systick fire interrupt in tickless mode then?. Please help me with my doubts or do provide any sample code. Thanks

I believe you need to be very careful when debugging sleeping code, as the debugger itself generates events that will wake the processor, so trying to “step” through the WFE/WFI instruction doesn’t act like you expect.

Try setting a breakpoint just after the WFE/WFI instruction, and resume before you get there to see if that works better.

@richard-damon has answered your question – you should avoid single stepping through WFI. Note also that Stop 2 itself behaves differently in debug mode. Normally there are some delays associated with waking from Stop 2, but when you are debugging those delays are virtually eliminated. Thus your interrupt latency is much shorter when debugging wake-ups from Stop 2 compared to not debugging. Just a heads up!

Thanks for the quick response @richard-damon @jefftenney . I checked by setting breakpoint after WFI function. Still the code is not waiting for interrupt. Could it be the Systick which wakes up the stop2 mode?, but will the Systick fire in tickless mode?. I am very confused. Could you provide a simple example code like using a gpio interrupt to wake from stop2 mode from idle task. I want to make sure that I haven’t overlooked any essential configuration setups in the process. Thanks in advance.

The default tickless (as I remember) mode still runs SysTick, but at a lower frequency so the system can keep time, as there may well be task with a finite but long delay present, and the SysTick can’t be set to an arbitrary long time.

Tickless means you don’t get EVERY tick interrupt, but it still tries to keep system time.

I would need to review what all Stop2 turns off, but if the peripheral clocks are still running (and thus SysTick still running) you will get periodic SysTick interrupts, but at a lower rate. But since the biggest divider on SysTick is about 16,000,000 for fast processors that still is somewhat short.

If you successfully enter Stop mode, Systick does stop. Thus it cannot wake you from Stop mode.

It seems likely you are not entering Stop mode at all, or even basic sleep. Remember that the WFI instruction doesn’t do anything if there are interrupts pending already. Much of the preparation for tickless sleep occurs with interrupts masked, and that masking continues all the way through the WFI instruction. Is it possible your application always has an interrupt pending by the time the WFI is reached?

Thank you @richard-damon and @jefftenney for the information. Much appreciated. It was due to a pending interrupt that prevented entry into stop 2 mode.

Thank you for reporting back.

Just for your info since apparently @jefftenney didn’t want to toot his own horn:
He did a great implementation of LPTIM based tickles idle for SMT32 and put it on gitlab GitHub - jefftenney/LPTIM-Tick: FreeRTOS Tick/Tickless via LPTIM
For my own purposes I implemented ulp.c a bit differently, but the lptimTick.c itself is pretty much all you can ask for.

1 Like

Thanks Oliver! I do recommend lptimtick.c for most applications that use STOP mode. The main benefit of using lptimTick.c is that FreeRTOS timekeeping continues during STOP mode. Without lptimTick.c, timekeeping stops during STOP mode (because systick stops during STOP mode).

FreeRTOS timekeeping is important in STOP mode if you are using vTaskDelay() or similar, or if you are using a FreeRTOS API call that needs to timeout, or if you are using FreeRTOS timers. If your application doesn’t need FreeRTOS timekeeping in STOP mode, then you probably don’t need lptimTick.c.