ThreadX tickless mode, can't get into Sleep mode
I have problems in getting this working. I moved from FreeRTOS to Azure RTOS, and I found out that in general there's lot less information on this RTOS. So I've been looking into the few resources, but I'm afraid I'm missing some important points. Articles in knowledge base show how to manage low power mode in ThreadX, but don't cover tickless mode (while an article about tickless mode is available for FreeRTOS). Examples in CubeMX repository are very simple. I also don't have much experience on STM32U5, and this doesn't help... I'm using CubeMX and HAL functions, IDE is STM32CubeIDE (current versions). Here's the problem:
I'm using ThreadX kernel running at 1 kHz, low power and tickless mode enabled. Two timers, one every 10 ms and another every 250 ms. RTC is interrupting every second, DMA2D interrupt also firing when LCD is updated. TDC is used for the LCD. Threads are waiting on events to perform some actions.Here are partial definitions of the functions related to low power management.
void App_ThreadX_LowPower_Timer_Setup(ULONG count)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Setup */
// Setup LPTIM4 to wakeup after (ticks * 1000) / TX_TIMER_TICKS_PER_SECOND ms
HAL_LPTIM_DeInit(&hlptim4);
hlptim4.Init.Period = LPTIM_MS_TO_TICK((count * 1000) / TX_TIMER_TICKS_PER_SECOND) - 1;
HAL_LPTIM_Init(&hlptim4);
/* USER CODE END App_ThreadX_LowPower_Timer_Setup */
}
void App_ThreadX_LowPower_Enter(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Enter */
HAL_SuspendTick();
// LPTIM4 used to wake up after the designated time
HAL_LPTIM_SetOnce_Start_IT(&hlptim4, LPTIM_CHANNEL_1);
// Enter sleep mode
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// *** DOESN'T GO TO SLEEP MODE!!! ***
/* USER CODE END App_ThreadX_LowPower_Enter */
}
void App_ThreadX_LowPower_Exit(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Exit */
HAL_ResumeTick();
/* USER CODE END App_ThreadX_LowPower_Exit */
}
ULONG App_ThreadX_LowPower_Timer_Adjust(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Adjust */
ULONG actual_ticks_slept;
ULONG elapsed_time_in_ms;
// Determine how long the processor actually slept
// Read counter and stop LPTIM
actual_ticks_slept = HAL_LPTIM_ReadCounter(&hlptim4);
// *** ALWAYS RETURNS 0 or 1 ***
HAL_LPTIM_SetOnce_Stop_IT(&hlptim4, LPTIM_CHANNEL_1);
elapsed_time_in_ms = LPTIM_TICK_TO_MS(actual_ticks_slept);
/* Convert elapsed time to ThreadX ticks. */
actual_ticks_slept = elapsed_time_in_ms / (1000 / TX_TIMER_TICKS_PER_SECOND);
return(actual_ticks_slept);
/* USER CODE END App_ThreadX_LowPower_Timer_Adjust */
}
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim) {
// NEVER FIRES
if (hlptim->Instance == LPTIM4) {
HAL_LPTIM_SetOnce_Stop_IT(hlptim, LPTIM_CHANNEL_1);
}
}
Of course I expect that RTC and DMA2D interrupts may interfere with the Sleep mode (they're happening at a slower rate compared to the kernel), but what happens is that the MCU never goes to sleep, even when i disable all the interrupts or if the LCD is not updated.
I noticed that ThreadX sets up the low power timer correctly to sleep few milliseconds, but it just doesn't happens.
My questions:
- Is debug interfering with sleep mode? Should I use HAL_DBGMCU_EnableDBGSleepMode()?
- If I insert HAL_PWR_EnableSleepOnExit() before entering Sleep mode should the MCU stay in sleep after servicing the interrupt?
- Should I check and clear interrupt flags before entering Sleep mode? In this case, what would be the best way (HAL or LL way)?
- Any idea about the reason why the MCU doesn't enter Sleep mode?
Any suggestion will be helpful, thank you.
