2025-12-10 3:58 PM
Hi,
I'm trying to implement a simple tickless idle on my STM32H7 running on the CM7 core i use TIM1 for TimeBase.
I followed the example from this video:
https://www.youtube.com/watch?v=hVlpf1Rm4Qo
My question is how it works, because the default implementation in FreeRTOSConfig.h is:
Why is time to sleep set to __x__ = 0; ???
#if configUSE_TICKLESS_IDLE == 1
#define configPRE_SLEEP_PROCESSING(__x__) \
do { \
__x__ = 0; \
PreSleepProcessing(__x__); \
}while(0)
#define configPOST_SLEEP_PROCESSING PostSleepProcessingWith this implementation and my PreSleepProcessing and PostSleepProcessing functions I use an LPTIM to wake up (similar to the video):
__weak void PreSleepProcessing(uint32_t ulExpectedIdleTime) {
/* place for user code */
HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_SET);
//HAL_TIM_Base_Stop_IT(&htim1);
HAL_SuspendTick(); // suspend SysTick timer
HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 0xFFFF, ulExpectedIdleTime); // enable interrupt from low-power timer
}
__weak void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* place for user code */
for (uint8_t i = 0; i < 8; i++) { // Check all NVIC pending registers (STM32 usually 0-2, loop to 8 is safer)
if (NVIC->ISPR[i] != 0) {
printf("WAKE SOURCE: Pending IRQ in NVIC->ISPR[%d]: 0x%08lX\r\n", i, NVIC->ISPR[i]);
// Optionally: more detailed decoding of bits
for (int bit = 0; bit < 32; bit++) {
if ((NVIC->ISPR[i] >> bit) & 1) {
int irq_number = (i * 32) + bit;
printf(" -> Active interrupt #: %d\r\n", irq_number);
}
}
}
}
actual_sleep_ticks = HAL_LPTIM_ReadCounter(&hlptim1);
HAL_LPTIM_TimeOut_Stop_IT(&hlptim1);
//HAL_TIM_Base_Start_IT(&htim1);
HAL_ResumeTick();
HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_RESET);
printf("[CM7] PT: %lu t, ST: %lu t \r\n", ulExpectedIdleTime, actual_sleep_ticks);
}
With the configPRE_SLEEP_PROCESSING macro shown above I get waking every 10 ticks, why ? i tryed turing off everything and still get woken up
[CM7] PT: 500 t,ST: 0 t
[CM7] PT: 490 t,ST: 0 t
[CM7] PT: 480 t,ST: 0 t
[CM7] PT: 470 t,ST: 0 t
[CM7] PT: 460 t,ST: 0 t
[CM7] PT: 450 t,ST: 0 t
[CM7] PT: 440 t,ST: 0 t
[CM7] PT: 430 t,ST: 0 t
[CM7] PT: 420 t,ST: 0 t
[CM7] PT: 410 t,ST: 0 t
[CM7] PT: 400 t,ST: 0 t
[CM7] PT: 390 t,ST: 0 t
[CM7] PT: 380 t,ST: 0 t
[CM7] PT: 370 t,ST: 0 t
[CM7] PT: 360 t,ST: 0 t
[CM7] PT: 350 t,ST: 0 t
[CM7] PT: 340 t,ST: 0 t
[CM7] PT: 330 t,ST: 0 t
[CM7] PT: 320 t,ST: 0 t
[CM7] PT: 310 t,ST: 0 tIn the video FreeRTOSConfig.h they use:
#if configUSE_TICKLESS_IDLE == 1
#define configPRE_SLEEP_PROCESSING PreSleepProcessing
#define configPOST_SLEEP_PROCESSING PostSleepProcessingAfter changing to that, my LPTIM starts to count but it counts multiple times — I thought it would count from 500 (500 from SysTick Overflow - i know) to zero and wake only once, but instead I see:
[CM7] PT: 500 t,ST: 510 t
[CM7] PT: 490 t,ST: 489 t
[CM7] PT: 486 t,ST: 485 t
...What am I missing? Why does it wake repeatedly instead of sleeping once for the full requested interval?
Thanks.