2026-04-10 12:44 PM
Hi all,
Thank you for looking at my thread.
I have started a proof of concept project that runs ThreadX and TouchGFX on a custom QSPI display on STM32F7.
I noticed from the documentation at https://support.touchgfx.com/docs/development/touchgfx-hal-development/scenarios/scenarios-configure-rtos that the following warning is highlighted.
Now indeed when I generate the code from CubeMX the MX_TouchGFX_Init is not getting called from anywhere, and in the documentation it suggests to call it from app_azure_rtos.c in the tx_application_define method.
However in such method the main thread is already been initialized.
If i replace App_ThreadX_Init with MX_TouchGFX_Ini, I am getting a TX_POOL_ERROR.
What am I supposed to do to initialize TouchGFX?
Thank you
2026-04-13 4:00 PM
I was able to make some progresses and get some code that would init the TouchGFX:
However I still need to figure out how to convert a screen into a framebuffer and send it to my spi display.
// In app_azure_rtos.c:
#if defined ( __ICCARM__ )
#pragma data_alignment=4
#endif
__ALIGN_BEGIN static UCHAR touchgfx_byte_pool_buffer[TOUCHGFX_APP_MEM_POOL_SIZE] __ALIGN_END;
static TX_BYTE_POOL touchgfx_app_byte_pool;
VOID tx_application_define(VOID *first_unused_memory)
{
/* USER CODE BEGIN tx_application_define */
/* USER CODE END tx_application_define */
VOID *memory_ptr;
if (tx_byte_pool_create(&tx_app_byte_pool, "Tx App memory pool", tx_byte_pool_buffer, TX_APP_MEM_POOL_SIZE) != TX_SUCCESS)
{
/* USER CODE BEGIN TX_Byte_Pool_Error */
/* USER CODE END TX_Byte_Pool_Error */
}
else
{
/* USER CODE BEGIN TX_Byte_Pool_Success */
/* USER CODE END TX_Byte_Pool_Success */
memory_ptr = (VOID *)&tx_app_byte_pool;
if (App_ThreadX_Init(memory_ptr) != TX_SUCCESS)
{
/* USER CODE BEGIN App_ThreadX_Init_Error */
/* USER CODE END App_ThreadX_Init_Error */
}
/* USER CODE BEGIN App_ThreadX_Init_Success */
/* USER CODE END App_ThreadX_Init_Success */
}
if (tx_byte_pool_create(&touchgfx_app_byte_pool, "TouchGFX App memory pool", touchgfx_byte_pool_buffer, TOUCHGFX_APP_MEM_POOL_SIZE) != TX_SUCCESS)
{
/* USER CODE BEGIN TouchGFX_Byte_Pool_Error */
/* USER CODE END TouchGFX_Byte_Pool_Error */
}
else
{
/* USER CODE BEGIN TouchGFX_Byte_Pool_Success */
/* USER CODE END TouchGFX_Byte_Pool_Success */
memory_ptr = (VOID*)&touchgfx_app_byte_pool;
if (MX_TouchGFX_Init(memory_ptr) != TX_SUCCESS)
{
/* USER CODE BEGIN MX_X-CUBE-TOUCHGFX_Init_Error */
/* USER CODE END MX_X-CUBE-TOUCHGFX_Init_Error */
}
/* USER CODE BEGIN MX_X-CUBE-TOUCHGFX_Init_Success */
/* USER CODE END MX_X-CUBE-TOUCHGFX_Init_Success */
}
}
2026-04-17 4:17 AM
Hello,
Your startup code looks fine to me.
To answer you second question; if you have set up TouchGFX to use single or full framebuffer and place by allocation, your framebuffer will be allocated outside the OS memory by TouchGFX in /target/generated/TouchGFXGeneratedHAL.cpp.
If your display has built-in GRAM, I would advise that you enable a Tearing Effect output on the display, and set up an interrupt to fire on that. When the signal indicates that it has left the active area, you can set up a DMA to transfer the active framebuffer to the display.
The code should be in TouchGFXHAL.cpp.
You can take a look at the Board Setup supplied for the STM32H573I-DK for an example of how this is done. That screen is driven using FMC, but the concept will be the same.