Skip to main content
LBESO.1
Associate
June 27, 2022
Solved

Problem with TouchGFX on STM32H747-DISCO: freezing while an other task runing with higher priority.

  • June 27, 2022
  • 10 replies
  • 6291 views

Hi ! I'm currently working on a STM32H747-DISCO with TouchGFX to test and discover this graphic library. 

My touchGFX app is only 2 screens with a button to go screen 1 or 2 with a slide animation.

But when I'm implementing an other task in FreeRTOS with a higher priority, TouchGFX freeze at some point when i'm changing screen. My goal was to see when the animations of the library would lag with an other task running on the M7.

Do you have any idea why the screen freeze ? It may be linked to the slide animation of screen.

This topic has been closed for replies.
Best answer by LBESO.1

Hi,

I just worked again on this issue, so here is an update and a summary about my problem.

-> The problem :

I'm working on a STM32H747-DISCO with the graphic library TouchGFX. I'm only using the M7 core under FreeRTOS. I added an other task called "CPU_Burner" to stress the CPU with some calculation to see how the TouchGFX's task respond and if the lagging effect is acceptable at some degrees. Of course the CPU_Burner task got an higher priority than the TouchGFX one or it won't get impacted.

When I flash the card and set up my CPU burner at 30% of the total load for example, after swiching between the two screens 1, 2 or 3 times, the TouchGFX GUI task freezed. And it's impossible to get it run again. The other task got no problem and is still runing, only TouchGFX and the screen remains fixed.

-> What I have done so far :

  • I debugged the program to see where TouchGFX is stucked and it seems that it's in the file "OSWrappers.cpp", in the function "void OSWrappers::signalVSync()". If I understood correctly, the message queue to tell TouchGFX that the VSYNC buffer is ready to render is full.
  • I added SystemView to monitor the application and i got the same result, TouchGFX stucked in signalVsync.
  • I tried different screens setup and others projects and it allways endup freezing.
  • For the MCU hint I disabled it and it didn't fixed anything. I will set up the precise address range for each external memory next week.

Some people managed to solve a similar issue with the MCU reconfiguration, in

this ST forum :

https://community.st.com/s/question/0D53W00000e067WSAQ/ui-stuck-in-takeframebuffersemaphore

-> The only solution that I Found :

  • On that ST forum someone had a problem close to mine and apparently related to the DMA/DMA2D. He found a solution for his problem, adding some code in TouchGFXHAL.cpp to this function :

void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef* hdsi)

" if (!refreshRequested)

          HAL::getInstance()->allowDMATransfers(); "

  • I did the same and now everything seems fine but I didn't really understood why. The problem seems related to a framebuffer lock but I can't manage to access it and monitor the lock and unlock.

I made a simplier project with System View with with the same issue. You can download it and try my project to see the freeze by yourself.

Thanks again to all the people trying to solve this ! :)

10 replies

Yoann KLEIN
ST Employee
June 27, 2022

Hello @LBESO.1​ ,

Can you please provide more information ?

  • Which version of TouchGFX are you using ?
  • Can you maybe share screenshots and attach your project so it could be easier to help you ?

Thanks,

/Yoann

Yoann KLEINST Software Developer | TouchGFX
LBESO.1
LBESO.1Author
Associate
June 27, 2022

Hey, thanks for that quick answer, I'm using TouchGFX V4.19.1.

I'm currently cleaning my project to get it easier to share. Will post everything as soon as i can.

LBESO.1
LBESO.1Author
Associate
June 27, 2022

Here is the amin files of my small project.

I use Get Run Time Stats from FreeRTOS to monitor the CPU's load with 2 tasks :

  • 1 for TouchGFX Normal priority
  • 1 to stress the CPU (some for loop and a delay after) in priority Normal+1

There is also a folder for SEGGER RTT because i'm using RTT printf when debugging with a JLINK probe.

My TouchGFX application is composed of 2 screens, nothing crazy :

  • First with a go to screen 2 button with slide animation and a icon going on/off when i press the joystick of the H747 board (led orange turn on/off)
  • Second with a go to screen 1 button with a slide animation, a button to turn on/off the blue led and changed a bulb picture on/off on the screen.

When I'm trying to get the application lagging it freeze the majority of the time and i get stuck with a screen like this one (here in during a slide) : 0693W00000NsovqQAB.jpg 

Yoann KLEIN
ST Employee
June 28, 2022

Hello,

Can you please share your whole project ? (TouchGFX project, .ioc file, and all the generated files).

I will try to reproduce your problem and debug your project.

Thank you,

/Yoann

Yoann KLEINST Software Developer | TouchGFX
LBESO.1
LBESO.1Author
Associate
June 28, 2022

Hi,

Here it is.

As far as i am researching the problem, i found out 2 things :

  • When my CPU burning task is runing for 50ms (50%) for example, and free 50ms (50%) for the other tasks, touchGFX allways take around 6-7% and the rest is stuck in the Idle Task. Isn't TouchGFX supposed to use eveything it can get ?
  • When TouchGFX task is freezed, it is stucked in OSWrappers::signalVSync(), osErrorResource returning -3 = ressource not available.

Thanks you.

LBESO.1
LBESO.1Author
Associate
June 30, 2022

Good morning,

Thanks for your attempt. I already tried on an other old project with several screens but same issue.

  • If I add a second task (stressing the CPU) with the same priority as the touchgfx task, everything works fine. Here putting it higher in priority regarding FreeRTOS make touchgfx task freeze at some point.

  • While freezing the touchGFX task is blocked calling osMessageQueuePut(vsync_queue,&dummy,0,0) in the OSWrappers. Returning -3.

In the project i sent you, there is a variable called cpu_burner_variable1 initialize at 10 (ms). And the osdelay at the end of the second task fixed to 100(ms). Could you just try with cpu_burner_variable1 over 60 for example and osDelay at 100 - cpu_burner_variable1?

It should highly increase the chance to get a Freeze.

I will try again from scratch adding second task with nothing in TouchGFX GUI’s screen and see if it Freezed.

Thanks you again for your help.

LBESO.1
LBESO.1Author
Associate
July 7, 2022

Hi,

Some updates over my problem :

  • I tried all the different animations for screen's transition in touchGFX and when i stress the CPU the task still freeze.
  • I noticed that I'm not using the optimize for size option (Os) of the builder but it doesn't really changed anything.
  • I used SEGGER SystemView to monitor the runing app. Here are the results. The touchGFX task will stopped after few screen transition.

0693W00000QKfutQAD.pngHere is the file SVDat if you want to look at it : https://drive.google.com/file/d/1Z3YvgpPZ90nGc7_hL4iW0EWeuJfaSyFT/view?usp=sharing

Thanks !

Xzhiy.1
Associate II
July 11, 2022

May be you cannot use osdelay() in task, use delay in task is not a good idea from my opinoin.

LBESO.1
LBESO.1Author
Associate
July 11, 2022

Hi, thanks for your advice.

But i already tried to use HAL_delay() or vTaskDelay(), same result.

An OsDelay() is calling vTaskDelay() so...

Xzhiy.1
Associate II
July 11, 2022

I'm Wong, for the reason of we can replace osDelay() with for(;;).

Xzhiy.1
Associate II
July 12, 2022

But...,osDelay() will call vTaskDelay() which will call vTaskSuspendAll(), this means you suspend the scheduler and leaves interrupts enabled, when TE (GPIO line)arrived, HAL_DSI_TearingEffectCallback()() is called in interrupt handler, DSI start to transfer the frame buffer data to screen with help from LDTC interface , and call OSWrappers::signalVSync() to signal TouchGFX egine to start render work again,this function put a message in queue and returned, this procedure avoid tear effect on srcreen.

so when CPU_BURNER_task1 run and suspend the scheduler somehow, TouchGFX engine lost chance to render. TE always come, and signalVSync() called again and again, the message queue just one place, you can't put them in?

You may instead osDealy() by for() to see what happed.

Xzhiy.1
Associate II
July 12, 2022

And use printf in ISR ususally not good way, a better way is printf to RAM and print out in a low pri task, it my personal opinoin.

LBESO.1
LBESO.1Author
Associate
July 12, 2022

Okay, It seems I don't really understood what you meant by "You may instead osDealy() by for() to see what happed."

My goal is to suspend my CPU_BURNER task to let TouchGFX's task breath and see what happen if i stress it too much.

I can't suspend a task with a loop? I need to use vtaskDelay() anyway no ?

Xzhiy.1
Associate II
July 12, 2022

I mean use for loops instead of osDealy(), something like this:

volatile uint32_t c;

for(uint32_t i = 0; i<1000000;++i)

{ ++c;}

it may not help, but I guess delay too long will cause somthing no good. especially with higher pri task.

LBESO.1
LBESO.1Author
Associate
July 12, 2022

oh yea sure

N. SANTINI
ST Employee
July 13, 2022

Hi,

I can see in your .icf file that your using both external SDRAM (from frame buffers most probably) and external FLASH (for graphic assets I guess), moreover you are using a Cortex-M7 based MCU.

This kind of unexpected crash in this context is usually due to an incorrect MPU (Memory Protection Unit) configuration.

The ARM Cortex-M7 is performing some optimizations at runtime, including "speculative accesses" that can sometimes lead try and access memory addresses of memory that are not even physically connected which lead to an hardfault !...

The only way to prevent that is to use the MPU configuration to first disable all accesses to the full address range of external memories and then define an MPU region per connected memory.

Please see our dedicated video:

https://www.st.com/content/st_com/en/support/learning/stm32-education/stm32-moocs/STM32_MPU_tips.html

Arm documentation :

Arm Cortex-M7 Processor Technical Reference Manual

Best regards,

Nicolas

LBESO.1
LBESO.1Author
Associate
July 21, 2022

Hello,

Thanks you for your answer.

I checked the MPU configuration on STM32CubeMX, and it's activated for 5 regions with :

  • Background region priviledged accesses only + MPU privileged default
  • MPU TEX field level 0,
  • All acces permitted
  • And others parameters disable.

The symptoms mentioned in the video for the speculative accesses read lock are different than mines. Here only the Touchgfx Task freezed, the main loop with other task is still running and i can still use the debugger.

I don't know if MPU is the real issue here...

Best regards,

LBESO.1
LBESO.1AuthorBest answer
Associate
July 22, 2022

Hi,

I just worked again on this issue, so here is an update and a summary about my problem.

-> The problem :

I'm working on a STM32H747-DISCO with the graphic library TouchGFX. I'm only using the M7 core under FreeRTOS. I added an other task called "CPU_Burner" to stress the CPU with some calculation to see how the TouchGFX's task respond and if the lagging effect is acceptable at some degrees. Of course the CPU_Burner task got an higher priority than the TouchGFX one or it won't get impacted.

When I flash the card and set up my CPU burner at 30% of the total load for example, after swiching between the two screens 1, 2 or 3 times, the TouchGFX GUI task freezed. And it's impossible to get it run again. The other task got no problem and is still runing, only TouchGFX and the screen remains fixed.

-> What I have done so far :

  • I debugged the program to see where TouchGFX is stucked and it seems that it's in the file "OSWrappers.cpp", in the function "void OSWrappers::signalVSync()". If I understood correctly, the message queue to tell TouchGFX that the VSYNC buffer is ready to render is full.
  • I added SystemView to monitor the application and i got the same result, TouchGFX stucked in signalVsync.
  • I tried different screens setup and others projects and it allways endup freezing.
  • For the MCU hint I disabled it and it didn't fixed anything. I will set up the precise address range for each external memory next week.

Some people managed to solve a similar issue with the MCU reconfiguration, in

this ST forum :

https://community.st.com/s/question/0D53W00000e067WSAQ/ui-stuck-in-takeframebuffersemaphore

-> The only solution that I Found :

  • On that ST forum someone had a problem close to mine and apparently related to the DMA/DMA2D. He found a solution for his problem, adding some code in TouchGFXHAL.cpp to this function :

void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef* hdsi)

" if (!refreshRequested)

          HAL::getInstance()->allowDMATransfers(); "

  • I did the same and now everything seems fine but I didn't really understood why. The problem seems related to a framebuffer lock but I can't manage to access it and monitor the lock and unlock.

I made a simplier project with System View with with the same issue. You can download it and try my project to see the freeze by yourself.

Thanks again to all the people trying to solve this ! :)