2023-04-08 11:43 AM - edited 2023-11-20 08:42 AM
I have completed the code and uploaded it to the following GitHub repository: https://github.com/gamarrita/Nucleo-L452_Azure_RTOS/tree/master/01_stop_mode_1
In my code, I am using the RTC and its wakeup capability to control sleep time. I am only using one thread, which sleeps for 5 seconds and then wakes up to sleep again.
The code works fine if I turn the power off and on again, but the CPU keeps entering and exiting a very high frequency if I just press the run or debug button.
Why stop mode works fine in one situation and fails in others?
And more important, how I can figure out, debug technique, to find out what is making CPU wakeup?
void App_ThreadX_LowPower_Timer_Setup(ULONG count)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Setup */
// Wakeup Counter = 2048
g_stop_ticks = count;
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,
(g_stop_ticks * 2048) / TX_TIMER_TICKS_PER_SECOND,
RTC_WAKEUPCLOCK_RTCCLK_DIV16);
/* USER CODE END App_ThreadX_LowPower_Timer_Setup */
}
/**
* @brief App_ThreadX_LowPower_Enter
* @param None
* @retval None
*/
void App_ThreadX_LowPower_Enter(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Enter */
HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_RESET);
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
/* USER CODE END App_ThreadX_LowPower_Enter */
}
/**
* @brief App_ThreadX_LowPower_Exit
* @param None
* @retval None
*/
void App_ThreadX_LowPower_Exit(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Exit */
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
// SystemClock_Config();
HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_SET);
/* USER CODE END App_ThreadX_LowPower_Exit */
}
/**
* @brief App_ThreadX_LowPower_Timer_Adjust
* @param None
* @retval Amount of time (in ticks)
*/
ULONG App_ThreadX_LowPower_Timer_Adjust(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Adjust */
return g_stop_ticks;
/* USER CODE END App_ThreadX_LowPower_Timer_Adjust */
}
/* USER CODE BEGIN 1 */
VOID refresh_thread_entry(ULONG initial_input)
{
while(1)
{
tx_thread_sleep(500);
}
}
2023-04-10 06:05 AM
Hi @dhs
after HAL_Init(), could you add the call to HAL_DBGMCU_DisableDBGStopMode(), then recheck?
regards
Haithem.
2023-04-10 09:42 AM
Hi Haithem
I called HAL_DBGMCU_DisableDBGStopMode(); and got the following behavior when runuig run and debugging:
Download verified successfully
Shutting down...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
I am not surprised that I'm getting these messages while debugging, but why while running ?
I started a new fresh project, very simple without RTOS, set yo RTC to wakeup and went to stop mode, a get those message only when debugging.
By the way, using HAL_DBGMCU_DisableDBGStopMode(); helps. Now power reset is not needed, and CPU goes to stop mode for the expected time.
2023-04-11 12:29 AM
Hi @dhs,
this is the expected behavior, as its name says, the HAL_DBGMCU_DisableDBGStopMode(), disables the debugging in stop mode, in this way you are sure that your system indeed entered in stop mode.
you can then put a break point in the App_ThreadX_LowPower_Exit() and when your systems quits the stop mode you'll be able to continue debugging.
regards
Haithem.
2023-04-11 06:14 AM
HI @Haithem Rahmani
1- Why I am able to use debug and low power modes without problems programming bare metal or FreeRTOS but not with ThreadX ?
2- I don't know if I am doing something wrong, adding HAL_DBGMCU_DisableDBGStopMode(), debugging becomes unusable. When I start the debug sesion starts ok, system stops on HAL_Init(). When I press Resumes, I got a lot of the following messages before sesion stops:
(adding or not breakpoint to sesion I get same behavior).
Target is not responding, retrying...
Target is not responding, retrying...
Shutting down...
Exit.
Later debug sesion stops and get following
STMicroelectronics RTOS Proxy. Version 0.13.1
Copyright (c) 2023, STMicroelectronics. All rights reserved.
Loading RTOS driver... ThreadX
Connecting to GDB server 127.0.0.1 on port 61234 ... Connected
Listen for GDB connection on port: 60000 ... Connected
Lost connection to GDB Server
Proxy stopped.
2023-04-12 12:22 AM
Hi @dhs
Unlike FreeRTOS, which have and "IDLE Thread" that is activated when no other threads are, ThreadX is blocked at the scheduler until a thread is ready.
for the HAL_DBGMCU_DisableDBGStopMode(), as said, it is useful to be sure that the system entered the STOP mode as it may happen that a pending IRQ interferes with the system and wakes it up. so the behavior is expected as the IDE looses connection to the target.
Now as you are sure that your application enters/exits the STOP mode correctly you can remove the call to that API and the debugger will continue to work correctly
regards
Haithem.
2023-04-12 12:39 PM
Hi @Haithem Rahmani
In may application has one thread which performs the following:
Turn led on -> tx_thread_sleep(20) -> Turn led off -> tx_thread_sleep(100)
I added the debug message "x_low_power_next_expiration"
I was expecting to receive the following sequence of messages:
20 ... delay of 20 ms
200 ... delay of 200 ms
20 ... delay of 20 ms
200 ... delay of 200 ms
and repeat for ever
But I got
19 ... delay almost 20ms
0 ... almost no delay
0 ... almost no delay
(a total of 14 zeros with almost no delay)
199 ... delay almost 200ms
0 ... almost no delay
0 ... almost no delay
(a total of 14 zeros with almost no delay)
I understand where the difference of 1 comes from, but I don't understand why the zeros that are between these values?
The CPU is actually going into sleep mode for 20 and 100 ticks in each case.
=19
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=199
=199
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=19
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
=0
/**
* @brief App_ThreadX_LowPower_Timer_Setup
* @param count : TX timer count
* @retval None
*/
void App_ThreadX_LowPower_Timer_Setup(ULONG count)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Setup */
uint32_t ticks_to_sleep;
#ifdef FM_DEBUG_UART_TX_TIME_ON_IDLE
fm_debug_uint32_uart(count);
#endif
g_lptim1_start = LPTIM1->CNT;
ticks_to_sleep = (32768 / 16) * count; // clock_freq / RTC_WAKEUPCLOCK_RTCCLK_DIV16
ticks_to_sleep /= TX_TIMER_TICKS_PER_SECOND;
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, ticks_to_sleep, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
/* USER CODE END App_ThreadX_LowPower_Timer_Setup */
}
/**
* @brief App_ThreadX_LowPower_Enter
* @param None
* @retval None
*/
void App_ThreadX_LowPower_Enter(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Enter */
// CPU goes to stop mode,
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
/* USER CODE END App_ThreadX_LowPower_Enter */
}
/**
* @brief App_ThreadX_LowPower_Exit
* @param None
* @retval None
*/
void App_ThreadX_LowPower_Exit(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Exit */
/*
* If CPU wakes up other reason but timer flag we must wait until
* expected time was elapsed. Debugger issues makes wake up CPU earlier
*/
HAL_ResumeTick();
SystemClock_Config();
/* USER CODE END App_ThreadX_LowPower_Exit */
}
/**
* @brief App_ThreadX_LowPower_Timer_Adjust
* @param None
* @retval Amount of time (in ticks)
*/
ULONG App_ThreadX_LowPower_Timer_Adjust(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Adjust */
static uint16_t cnt_drift = 0;
ULONG cnt_ret;
g_lptim1_end = LPTIM1->CNT;
cnt_ret = (g_lptim1_end - g_lptim1_start);
cnt_ret *= TX_TIMER_TICKS_PER_SECOND;
cnt_ret += cnt_drift;
cnt_drift = cnt_ret % 2048; // 2048 = lptim_clok_frq / clock_prescaler
cnt_ret /= 2048;
return cnt_ret;
/* USER CODE END App_ThreadX_LowPower_Timer_Adjust */
}
/* USER CODE BEGIN 1 */
VOID refresh_thread_entry(ULONG initial_input)
{
while(1)
{
HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_SET);
tx_thread_sleep(20);
HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_RESET);
tx_thread_sleep(200);
}
}
2023-04-13 02:32 AM
Hi @dhs ,
in the App_ThreadX_LowPower_Enter(), Could you add a call to HAL_SuspendTick()?
and retest.
regards
Haithem.
2023-04-13 04:57 PM
Hi @Haithem Rahmani
I included the HAL_SuspendTick(); and tested again, same behavior, a bunch of zeros appears.
Regards,
Daniel.
2023-06-12 07:19 AM
I'm having the exact same problem! Did you find a solution or workaround?