cancel
Showing results for 
Search instead for 
Did you mean: 

VSCode: RtosProxy error with big thread stack on ThreadX

PierreB
Associate III

During a debugging session, when `tx_thread_create` is called with a "big" stack size (1024*10 for example) and the "serverRtos" is enabled, the debugger is disconnected with an error: "Remote communication error. Target disconnected: No error."

 

Here the debug console logs (full log attached):

 

Spoiler
To client: {"seq":0,"type":"event","event":"output","body":{"category":"proxy","output":"RTOS proxy: Lost connection to GDB Server\r\n"}}
RTOS proxy: Lost connection to GDB Server
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"{\"label\":\"\",\"value\":[{\"label\":\"Driver\",\"value\":\"ThreadX\"},{\"label\":\"Kernel state\",\"value\":\"Not started\"}]}\n"}}
{"label":"","value":[{"label":"Driver","value":"ThreadX"},{"label":"Kernel state","value":"Not started"}]}
GDB result: 36 done
To client: {"seq":0,"type":"response","request_seq":25,"command":"cdt-gdb-tests/executeCommand","success":true,"body":{"status":"Ok","result":{},"console":["monitor rtos -m state\n","{\"label\":\"\",\"value\":[{\"label\":\"Driver\",\"value\":\"ThreadX\"},{\"label\":\"Kernel state\",\"value\":\"Not started\"}]}\n"]}}
To client: {"seq":0,"type":"event","event":"output","body":{"category":"proxy","output":"RTOS proxy: Proxy stopped.\r\n"}}
RTOS proxy: Proxy stopped.
GDB notify async: thread-exited,id="1",group-id="i1"
GDB notify async: thread-group-exited,id="i1"
GDB result: 37 error,msg="Remote communication error. Target disconnected: No error."

And the very basic code used:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    app_threadx.c
  * @author  MCD Application Team
  * @brief   ThreadX applicative file
  ******************************************************************************
    * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "app_threadx.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
TX_THREAD tx_app_thread;
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
VOID th_main(ULONG thread_input)
{
    while (1)
    {
        tx_thread_sleep(1);
    }
}
TX_THREAD p_thMain;
#define MAIN_THREAD_STACK_SIZE (1024*10)
CHAR thMain_stack[MAIN_THREAD_STACK_SIZE];
/* USER CODE END PFP */

/**
  * @brief  Application ThreadX Initialization.
  *  memory_ptr: memory pointer
  * @retval int
  */
UINT App_ThreadX_Init(VOID *memory_ptr)
{
  UINT ret = TX_SUCCESS;
  TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;

  /* USER CODE BEGIN App_ThreadX_MEM_POOL */
  /* USER CODE END App_ThreadX_MEM_POOL */
  CHAR *pointer;

  /* Allocate the stack for tx app thread  */
  if (tx_byte_allocate(byte_pool, (VOID**) &pointer,
                       TX_APP_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
  /* Create tx app thread.  */
  if (tx_thread_create(&tx_app_thread, "tx app thread", tx_app_thread_entry, 0, pointer,
                       TX_APP_STACK_SIZE, TX_APP_THREAD_PRIO, TX_APP_THREAD_PREEMPTION_THRESHOLD,
                       TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START) != TX_SUCCESS)
  {
    return TX_THREAD_ERROR;
  }

  /* USER CODE BEGIN App_ThreadX_Init */
  tx_thread_create(&p_thMain, "Main Thread", th_main, 0, thMain_stack,
                       MAIN_THREAD_STACK_SIZE, TX_APP_THREAD_PRIO, TX_APP_THREAD_PREEMPTION_THRESHOLD,
                       TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START);

  /* USER CODE END App_ThreadX_Init */

  return ret;
}
/**
  * @brief  Function implementing the tx_app_thread_entry thread.
  *   thread_input: Hardcoded to 0.
  * @retval None
  */
void tx_app_thread_entry(ULONG thread_input)
{
  /* USER CODE BEGIN tx_app_thread_entry */
    while (1)
    {
        tx_thread_sleep(100);
    }
  /* USER CODE END tx_app_thread_entry */
}

  /**
  * @brief  Function that implements the kernel's initialization.
  *   None
  * @retval None
  */
void MX_ThreadX_Init(void)
{
  /* USER CODE BEGIN Before_Kernel_Start */

  /* USER CODE END Before_Kernel_Start */

  tx_kernel_enter();

  /* USER CODE BEGIN Kernel_Start_Error */

  /* USER CODE END Kernel_Start_Error */
}

/**
  * @brief  App_ThreadX_LowPower_Timer_Setup
  *   count : TX timer count
  * @retval None
  */
void App_ThreadX_LowPower_Timer_Setup(ULONG count)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Timer_Setup */

  /* USER CODE END  App_ThreadX_LowPower_Timer_Setup */
}

/**
  * @brief  App_ThreadX_LowPower_Enter
  *   None
  * @retval None
  */
void App_ThreadX_LowPower_Enter(void)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Enter */

  /* USER CODE END  App_ThreadX_LowPower_Enter */
}

/**
  * @brief  App_ThreadX_LowPower_Exit
  *   None
  * @retval None
  */
void App_ThreadX_LowPower_Exit(void)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Exit */

  /* USER CODE END  App_ThreadX_LowPower_Exit */
}

/**
  * @brief  App_ThreadX_LowPower_Timer_Adjust
  *   None
  * @retval Amount of time (in ticks)
  */
ULONG App_ThreadX_LowPower_Timer_Adjust(void)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Timer_Adjust */
  return 0;
  /* USER CODE END  App_ThreadX_LowPower_Timer_Adjust */
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

 

17 REPLIES 17
PierreB
Associate III

Hi,

 

Same, I tried with 0x10000 for both too.

PierreB
Associate III

Everything runs as expected in CLion and STMCubeIDE, but when I use the exact same code in VSCode, I have the issue.

Can you reproduce the bug with the project I shared with you?

Is there any additional information I can provide to help move forward?

Nawres GHARBI
ST Employee

is it possible to share your project ? 

Nawres GHARBI
ST Employee

The thread creation with min stack size "#define MAIN_THREAD_STACK_SIZE (1024*10)" is causing overlap between .bss and ._user_heap_stack

to fix that you can define the creation of the main thread task as following: 

instead of:

  tx_thread_create(&p_thMain, "Main Thread", th_main, 0, thMain_stack,
                       MAIN_THREAD_STACK_SIZE, TX_APP_THREAD_PRIO,   TX_APP_THREAD_PREEMPTION_THRESHOLD,
                       TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START);
 
use: 
  CHAR *thMain_stack;
  if (tx_byte_allocate(byte_pool, (VOID **)&thMain_stack, MAIN_THREAD_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS) {
    // Handle allocation error
}
  tx_thread_create(&p_thMain, "Main Thread", th_main, 0, thMain_stack,
                       MAIN_THREAD_STACK_SIZE, TX_APP_THREAD_PRIO, TX_APP_THREAD_PREEMPTION_THRESHOLD,
                       TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START);
 
 This allocates the stack from the ThreadX byte pool, reducing static .bss usage and preventing overlap. 
please pay attention also to heap and stack size that I modified
 
NawresGHARBI_0-1761659175740.pngNawresGHARBI_1-1761659196859.png

 

PierreB
Associate III

Thank you for taking the time to help me.

I tried implementing your suggestion, but unfortunately it doesn't work any better. The issue persists even after allocating the stack from the ThreadX byte pool as you described.

I have the impression that the problem is elsewhere because it works correctly on STM32CubeIDE.

Nawres GHARBI
ST Employee

could you try this project

PierreB
Associate III

It doesn't crash because the thMain_stack failed to allocate so the thread is not created.

You must extend the TX_APP_MEM_POOL_SIZE