cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX hangs up at higher processor load

Sandro_K
Associate III

Hello!
I have an STM32F777 with FreeRTOS and TouchGFX. An SPI display is controlled in partial framebuffer mode via SPI4 and DMA. The implementation is the same as in the TouchGFX demo projects with partial framebuffer (NUCLEO_C071RB + GFX01M2). I have also attached my display SPI library.
The vSync signal is implemented at 60Hz via a software timer, as the hardware does not provide such a signal.
My hardware has an Ethernet port that provides a web server with the LwIP stack. This generates many interrupts during high data traffic, which puts a greater load on the processor.
During operation, this leads to a deadlock of TouchGFX after a few minutes. TouchGFX gets stuck in the function “getBlockForTransfer(Rect& rect)” in the line “assert(state[sendingBlock] == DRAWN);” (File: FrameBufferAllocator.hpp).
After that, the display is no longer updated.

If you need further information, please let me know.

TouchGFX config.png

TouchGFX_hang.png


Attached is the configuration.
I hope someone can help me.

9 REPLIES 9
PeterVang
ST Employee

Hello Sandro,

I cannot immediately tell why your deadlock occurs, but I think I can help you with the high MCU load from TouchGFX. The display implementation in "NUCLEO_C071RB + GFX01M2" is designed to work without an OS, so it will simply busy wait when transferring to the display, which means high MCU load. Since you have an OS in your project, it should instead be sleeping while waiting for the display transfer.

To implement this, you can look at the "NUCLEO-H563ZI + RVA35HI" for inspiration. This project is setup with partial framebuffer and FreeRTOS, and sleeps while waiting for display transfers. You should pay special attention to the functions called FrameBufferAllocatorWaitOnTransfer, waitUntilTransmitEnd and waitUntilCanTransferBlock.

Best regards,

Peter

Hello, thank you for your reply.

In the suggested example project, the vsync signal is measured with a timer. In my case, this signal does not exist and is generated by the FreeRTOS timer.

Should the mechanism from the function void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin) still be implemented and a FreeRTOS timer be used instead of the TE pin,

or can the function touchgfx::OSWrappers::signalVSync(); be called directly by a 60 FPS FreeRTOS timer?

PeterVang
ST Employee

Hello Sandro,

The TE signal in the example project is used to ensure that the display can be updated without showing visual tearing. If you do not have the TE signal available, you will most likely experience some visual tearing no matter what you do. But in this case, you can skip the TE and line counter mechanisms from the example project and just call "touchgfx::HAL::getInstance()->vSync()" and "touchgfx::OSWrappers::signalVSync()" directly from a timer with the desired tick rate.

Regards,

Peter

Sandro_K
Associate III

I compared my project with the “NUCLEO-H563ZI + RVA35HI” project. I added the semaphores and the functions “void FrameBufferAllocatorWaitOnTransfer()” and “void waitUntilTransmitEnd()”.

However, I noticed that these are never called by TouchGFX. What do I need to do to activate this?

Sandro_K
Associate III

The problem that the functions were not being called has been resolved, and now the weak functions are being overwritten. I did not have the implemented functions in the touchgfx namespace.

Hello Peter,

I have implemented the FrameBufferAllocatorWaitOnTransfer and waitUntilTransmitEnd functions, and there was also a weak implementation for this which is now overwritten.

However, there is neither a weak implementation nor a place where it is called for the waitUntilCanTransferBlock function.
Do I need this function? Do I need to activate something else in CubeMX to make this function available?

PeterVang
ST Employee

Hello Sandro,

The TouchGFX project will work without this function manually implemented, but CPU load will be higher than need, because it will busy wait instead.

There should be a weak implementation of it in TouchGFXGeneratedHAL.cpp whenever you are using partial framebuffer. I think the function was introduced in TouchGFX 4.25.0. What version of TouchGFX are you using?

Hello, I am using TouchGFX version 4.25.0.

I am uncertain whether I need to adjust the CubeMX configuration to enable the missing functions. I have searched the entire project but cannot locate the waitUntilCanTransferBlock function. Consequently, it is not being called.
You find attached an image of my settings. Do I need to adjust anything else?

Just as a reminder, I don't have a TE pin (the display doesn't have one) and vSync is generated by a FreeRTOS timer.

Sandro_K_0-1755584113907.png

 

PeterVang
ST Employee

Hello Sandro,

You need to set the "Partial Framebuffer VSync" to enabled, to to have this weak function generated and called by the framework.

To elaborate what I wrote earlier: If you do not have a TE signal or any other feedback from the display about where it is in its drawing cycle, you will most likely always risk to have tearing in your GUI. And in this case, I am sure I see the point in implementing "waitUntilCanTransferBlock", if you do not know when it is "safe" to transfer.