cancel
Showing results for 
Search instead for 
Did you mean: 

UI stuck in takeFrameBufferSemaphore

Gom
Associate II

Hi

When switching between screens fast, my UI always ends up freezing. Debugging reveals that it waits forever, waiting for the frame buffer semaphore.

Here is the call stack:

0693W000008ww2rQAA.png 

Inspecting other running tasks shows nothing wrong. Only the graphics task should touch the frame buffer semaphore, right? So it should never deadlock?

Environment:

  • IDE: Atollic
  • RTOS: FreeRTOS
  • TouchGFX: 4.16
  • OS: Windows
69 REPLIES 69

Yes i would like to have a look if possible.

@Martin KJELDSEN​ We're using F7, and I think we based it on F769I dev board (started more than a year ago). I think you already have my HAL files.

Hi @Martin KJELDSEN​  : I could not find you email ID on your profile. So, can you please personal message your email ID to share the project ?

I will send you a PM.

Hi guys,

Can you try something? In the beginning of your TE/Vsync interrupt try to force the DMA completion. Something like

   ....
   if (((TouchGFXHAL*)(touchgfx::HAL::getInstance()))->getDMARuning())
  {
        count++;
        if(count> 60)
        {
            touchgfx::HAL::getInstance()->signalDMAInterrupt();
            count= 0;
        }
        return;
    }else{
        count= 0;
    }
  
  bool TouchGFXHAL::getDMARuning(){
    return dma.isDMARunning();
  }

This will tell us if DMA2D is stopped somehow. If this solves the issue, then you could try to inspect your DMA2D registers for configuration errors or otherwise.

Also, what is the complexity of your applications? Are you turning off interrupts at some point and reenabling them?

Hi @Martin KJELDSEN​ 

So I added your code into the LTDC IRQ handler :

void LTDC_IRQHandler(void)
{
    if (LTDC->ISR & 1)
    {
        LTDC->ICR = 1;
        if (LTDC->LIPCR == lcd_int_active_line)
        {
			if (((STM32F7HAL*)(touchgfx::HAL::getInstance()))->getDMARuning())
			{
			  count++;
			  if(count> 600)
			  {
				  touchgfx::HAL::getInstance()->signalDMAInterrupt();
				  count= 0;
			  }
			  return;
			}else{
			  count= 0;
			}
            //entering active area
            LTDC->LIPCR = lcd_int_porch_line;
            HAL::getInstance()->vSync();
            OSWrappers::signalVSync();

In the end :

  • I hit the return often, not sure if it's an issue or not.
  • I hit the 600 count sometimes, and then it works again.

So I guess signalDMAInterrupt is unblocking everything.

From what I see, the DMA2D registers have no error (ISR is 0x00). Should I check something in particular in the registers ? (I shared them at the beginning of this thread).

Hi @Martin KJELDSEN​ :

We were able to finally solve the problem with UI getting stuck.

After further analysis we were able to find out that, when this issue is observed, the DMA2D remained in locked state and transfer status as busy forever. As such there were no error in DMA2D registers. Therefore we re-configured the MPU to avoid speculative read accesses. This solved our problem.

The MPU configuration example (section 6.2.7) in https://www.st.com/resource/en/application_note/dm00287603-lcdtft-display-controller-ltdc-on-stm32-mcus-stmicroelectronics.pdf helped us in solving the problem.

Hi @AKG​ ,

Were you using the MPU before ? We're not using it, so i'm not sure I have the same problem :\

Hi @vtunr​ : The example just shows how to correctly initialize the SDRAM and QSPI.

if you are using external SDRAM and QSPI then that should be applicable to you as well.

@AKG​ thanks for your answer. My question was more about how the MPU was configured when you had the issue ?

  1. Was it enabled and it was causing issue because misconfigured ?
  2. Was it not enabled and enabling it with correct configuration fixed your issue ?

On our side, MPU is disable, so if it's 1. for you, I guess we have a different problem :\