cancel
Showing results for 
Search instead for 
Did you mean: 

ThreadX with stop mode 1 works fine after power reset, but fail on run and debug.

dhs
Senior

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?


_legacyfs_online_stmicro_images_0693W00000bhkp9QAA.png

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);
	}
}

10 REPLIES 10
Haithem Rahmani
ST Employee

Hi @dhs​ 

after HAL_Init(), could you add the call to HAL_DBGMCU_DisableDBGStopMode(), then recheck?

regards

Haithem.

dhs
Senior

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.

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.

dhs
Senior

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.

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.

dhs
Senior

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)

  • LPTIM 1 is free running, LSE 32768, I am using it to measure time elapsed during sleep.
  • RTC will wakeup CPU in tx_low_power_next_expiration ticks

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);
	}
}

Haithem Rahmani
ST Employee

Hi @dhs​ ,

in the App_ThreadX_LowPower_Enter(), Could you add a call to HAL_SuspendTick()?

and retest.

regards

Haithem.

dhs
Senior

Hi @Haithem Rahmani​ 

I included the HAL_SuspendTick(); and tested again, same behavior, a bunch of zeros appears.

Regards,

Daniel.

I'm having the exact same problem! Did you find a solution or workaround?