Skip to main content
Associate II
April 28, 2025
Solved

HardFault (PC=0x40) when Switching Pages with Buttons in TouchGFX on STM32U5 + FreeRTOS

  • April 28, 2025
  • 1 reply
  • 759 views

Hello everyone, I am a first-year university student. I am developing a GUI application on the STM32U585 using TouchGFX Designer and FreeRTOS, and I have encountered some issues. Due to my lack of experience, I would like to ask for your advice on how to solve these problems. Here is my GitHub repository for the code(https://github.com/weixuna/GPDMA_AMOLED_). Device information:

  • MCU: STM32U585CIU6
  • RTOS: FreeRTOS
  • GUI: TouchGFX
  • IDE: STM32CubeIDE
  • GPDMA enabled
  • The display is AMOLED, and the MCU communicates with the screen via QSPI in OCTOSPI mode.

Phenomenon:

  • I added two buttons in TouchGFX Designer.
  • When I swipe to switch to a page (Screen) with two buttons, the program sometimes crashes and enters a HardFault.
  • The crash happens during or after the page transition animation.
  • If I add transition animations such as Cover, Wipe, or Block, there will be screen corruption (garbled display). If I use the Slide animation, there is no problem.

Debug information:

  • When the HardFault occurs, the PC is 0x40 (sometimes 0x2).
  • The call stack often points to TouchGFXGeneratedHAL::enableInterrupts() or the DMA2D interrupt.
  • The LR and other registers in the fault stack frame contain abnormal values.
  • I have already configured the MPU, but I am not sure if it is correct.
  • FreeRTOS configMINIMAL_STACK_SIZE is 128
 
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)80000)

const osThreadAttr_t defaultTask_attributes = {
 .name = "defaultTask",
 .priority = (osPriority_t) osPriorityNormal,
 .stack_size = 128 * 4
};
osThreadId_t GUI_TaskHandle;
const osThreadAttr_t GUI_Task_attributes = {
 .name = "GUI_Task",
 .priority = (osPriority_t) osPriorityNormal,
 .stack_size = 10240 * 4
};
void MPU_Config(void)
{
 MPU_Region_InitTypeDef MPU_InitStruct = {0};
 MPU_Attributes_InitTypeDef MPU_AttributesInit = {0};

 /* MPU */
 HAL_MPU_Disable();

 /** Attribute 0: FrameBuffer (Normal Memory, Non-Cacheable) */
 MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER0;
 MPU_AttributesInit.Attributes = INNER_OUTER(MPU_NOT_CACHEABLE);
 HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);

 /** Attribute 1: OSPI (Device Memory) */
 MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER1;
 MPU_AttributesInit.Attributes = MPU_DEVICE_nGnRnE;
 HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);

 /** Region 0: FrameBuffer */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 MPU_InitStruct.BaseAddress = 0x20000000U;
 MPU_InitStruct.LimitAddress = 0x20080000U;
 MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
 MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /** Region 1: OSPI */
 MPU_InitStruct.Number = MPU_REGION_NUMBER1;
 MPU_InitStruct.BaseAddress = 0x420D1000U;
 MPU_InitStruct.LimitAddress = 0x420D2000U;
 MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER1;
 MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /* MPU */
 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

Any help or experience would be greatly appreciated!
weixun_0-1745833471171.jpegweixun_1-1745833506817.pngweixun_2-1745833698990.png

 

 

Best answer by GaetanGodart

If it is not smooth, then you are probably loosing frame because it takes too long to render (it should render in 16ms or less to have 60 fps).

You can check the render time the same way I do it in the video.

You can also see that different transitions need to render more or less area. To make sure you keep a smooth GUI, you should limit the area that is invalidated during your transition by either using a transition that invalidate less pixels or even just not using any transition.

 

Regards,

1 reply

GaetanGodart
Technical Moderator
April 28, 2025

Hello @weixun ,

 

So you have made a custom board from what I understand.

 

Can you try to disable MPU.
Can you try to increase stack and heap size of FreeRTOS.

The issue only happens when going to a screen with 32 buttons? If you remove one of the buttons it works fine?

The slide animation works? You have added the animation buffer?

 

Regards,

weixunAuthor
Associate II
April 28, 2025

 

Hello,GaetanGodart.

I'm very sorry to trouble you again. I tried setting the heap of FreeRTOS to 80,000 and the stack to 512, but the screen still froze. When MPU and icache are enabled, it is normal to delete a button and slide the page (but in some cases, the page may freeze). I disabled MPU and icache, and sliding to a page with a button is normal. I think it must be a mistake in my MPU configuration. I'm not very clear about adding animation buffers.

GaetanGodart
Technical Moderator
April 28, 2025

No problem! :)

 


When MPU and icache are enabled, it is normal to delete a button and slide the page (but in some cases, the page may freeze).

I did not understand that. When you have MPU and Icache enabled, you sometimes have a freeze even if there is only 1 button on the new screen (instead of 2 buttons where it happens all the time)?

 

When using the slide animation, you need to add a buffer for that animation : animation storage video 

But maybe it is already set by default.

 

If it works fine without MPU and Icache, you could just continue on working without them as long as you have enough performance for your application, maybe it is not the most important for you.

 

Regards,