374 views
in System Integration by

Hi all,

I am using the STM32F746-Discovery build environment as base for our custom board. I just updated from v9.00 to v11 and wanted to test the new binary.

Now there comes a Fifo-Underrun from the LTDC. This is happening during the first call in the while(1)-loop of the gui task.

I have read in the forum, that aligning the Buffer-Width to 64Bytes is key. This was already fullfilled, since we use a 800x460Px Display with RGBA8888 color-scheme -> 800x4 = 3200, 3200/64=50

The Double Framebuffers are located in external SRAM, as in the discovery-Board.

What could cause the FIFO-Underrun? Does the MCU eat up all the transfers and no much is left for the ltdc-dma to fetch current pixel-data?

It could be a curious coincident, but the interrupt is mostly hitten, when the "CleanSurfaceCache" is working, see following stacktrace:

greetings Daniel

Edit: I inserted many debug-printf-s before correctly debugging with cube-ide. Then sometimes, the gui started correctly. But when inputting some Touch-inputs, the system hangs. Because all unimplemented Handlers are sent to DefaultHandler, that has a while(1) loop, sothat the complete system stands still... I recognized a "chopping" effect for a brief time, as shown in the picture in this question: https://ask.embedded-wizard.de/6174/chopping-occuring-on-stm32f769-disco?show=6174#q6174

2 Answers

0 votes
by
 
Best answer

Hi Manfred,

After some testing, I conclude, that with the call to

EwBspGraphicsConcurrentOperation(0);

the flickering has gone mostly away. I made tests with the interrupt-callback fetching in a while(1) loop and this only tripped once, so mainly the error is gone.

Changing the color format to a less transfer-speed demanding rgb565 is not possible, since the gui has some very light transitions in it, that would have suffered from color-steps, that would be visible. Over all, even the swipe-animations are all flawless as before, so the reduced over all performance does not degrade the look and feel...

Thanks for investigating this bug with me!

greetings, Daniel

0 votes
by

Hi Daniel,

it is always difficult to find the root cause without having the custom specific board on the table...

Some questions to have a common understanding: You are updating from version 9.00 to version 11, which is a huge step (see our Release Notes and also the target specific notes within the file ReadMe.txt in the root directory of the Build Environment).

Are there any other changes? Hardware changes? SDK changes? Compiler? This is important, so that there are not too many changes in one step.

Are you using the new Heap Manager or still TLSF memory manager? Have you seen the new configuration file ewconfig.h, which is now used to configure the entire project (without the need for all the compiler settings in the makefile or project file).

Can you share the entire startup message?

Best regards,

Manfred.

 

by

Hi Manfred,

yes, 9.0 to 11.0 is a huge step. I made a diff between the unchanged build-environments and a diff between 9.0 and our current standing. it was quite an effort to get the ew_bsp files changed correctly, since we had customized them quite a bit.

Hardware had not been changed. Same custom hardware before and after the upgrade.

SDK? I upgraded all the third-party things in the original build environment. So arm-gcc, stm hal and such things are upgraded.

I have inherited the project with the gcc-make build-chain used. Until now i used this. When i dodged this error (the system halts completely, since Default_Handler was catching it in a while(1) loop) but to figure out, what was going on, i actually had to debug in some form. there was a anchient gdb-bat script, that referenced to a path, that i do not have. So i used your project-file for cubeIDE and changed all the settings to match with the makefile. I debugged with this.

Edit: the error is reproducible with both, cubeIDE and make build binaries

tl;dr: currently using make + cubeIDE

Since now tlsf is not in the build-environment for v11, i have mostly used the new main and ewmain files and made our changes there again to call our additional custom functions. I think therefore, I'm now using the new Heap Manager.

---------------------------------------------
Target system                                xxxxxxxxxx Bedienteil
Color format                                 RGBA8888
MemoryPool address                           0xC0177000
MemoryPool size                              13705216 bytes
Framebuffer address                          0xC0000000
Doublebuffer address                         0xC0E89000
Display size                                 800 x 480
Framebuffer size                             800 x 480
EwScreenSize                                 800 x 480
Graphics accelerator                         DMA2D
Warp function support                        enabled
Vector graphics support                      enabled
Bidirectional text support                   enabled
Gradients support                            enabled
Compression support                          enabled
Index8 bitmap resource format                enabled
RGB565 bitmap resource format                enabled
Native bitmap resource format                enabled
Native destination bitmap support            enabled
Operating system                             FreeRTOS
External Flash memory                        QSPI Flash
Linker section for bitmap pixel              .SectionEwResource
Linker section for font pixel                .SectionEwResource
Linker section for font metrics              .SectionEwResource
Linker section for string constants          .SectionEwResource
Toolchain                                    GCC
C-Compiler version                           9.3.1
Build date and time                          Nov 30 2022, 18:29:49
Runtime Environment (RTE) version            11.00
Graphics Engine (GFX) version                11.00
Max surface cache size                       2097152 bytes
Glyph cache size                             256 x 256
Max issue tasks                              100
Surface rotation                             0
---------------------------------------------

What i have done in the meantime:

I have commented out the while(1) loop in the LTDC_ER_IRQHandler. So we ignore the Error and let the system run further. Now the GUI starts normally, but with the "chopping" effect comming up every now and then. We have an analog clock in the gui with a seconds indicator. So EW has to redraw the watch every second. The chopping-effect is quite syncronious to this update interval.

I discovered right now: while the device is heating up, there is an animated background. No "chopping"/flickering can be visually observed.

When the device is in "standby", there is no animation. "animation" is fading in and out an alpha-blended image in the background of about 2/3 of the whole display. The timer for updating the animation has a period of 234ms. I expected to have the flickering more often than in standby, since the gui has to run more often than before.

Could that correspond to switching between framebuffers in the middle of the image?

As i understand, this is handled in the TargetSpecific/ew_bsp_display.c. I will have a look into this now.

Thanks,

Daniel

by
Hi Daniel,

thanks for your detailed answer.

The switching between the framebuffers should happen V-synchronous. The 'chopping' effect seems to happen during intensive memory accesses from LTDC, CPU and DMA2D. Maybe, if you just have an animated background, there is not so much parallel activities of CPU and DMA2D so that the LTDC get enough data. If the UI update is more complex so that CPU and DMA2D consumes a higher memory bandwidth, the LTDC get some buffer underflow.

How is your SDRAM connected - is it a 16bit bus or a 32bit bus? Can you reduce the refresh rate of your display so that the required memory bandwidth of the LTDC is lower? 800x480xRGBA8888 is a huge amount of data.

Best regards,

Manfred.
by
Hi Manfred,

as in the discovery-board, the same SRAM-Chip is used and it is only conntected with 16bit...

I understand, that the chopping is gonna be more likely to happen, when the gui/DMA2D has more to do. I didn't mention: the animation is additional to the analog clock active. So:

Standby: no animation, only analog clock, copping can be seen

Heating up: animation and analog clock, no chopping can be seen.

But now a bigger part of the screen has to be redrawn. But probably more things have to be "calculated" in the cpu and more picture content has to be fetched from the external qspi-flash. This takes time where little to no acces to the SRAM is performed and this gets the LTDC-DMA enough time to fill its buffer.

When we only have to update the perimeters of the clock, fetching and calculation probably gets faster and we have excessive write to the framebuffer/access to the Heap-Manager area placed between the two framebuffers in the SRAM. Is there any mechanics to slow down the access to the sram from the cpu/DMA2D to have guaranteed time for the LTDC to fetch its data?

I can imagine a max pixel/ms ratio where when exceeded, the main process enters a short "sleep"...

greetings,

Daniel
by

Hi Daniel,

there is one function in ew_bsp_graphics.c that can be used to avoid parallel activities of DMA2D and CPU:

/*******************************************************************************
* FUNCTION:
*   EwBspGraphicsConcurrentOperation
*
* DESCRIPTION:
*   The function EwBspGraphicsConcurrentOperation configures the operation mode
*   of DMA2D and CPU. If concurrent operation is enabled, the CPU will work in
*   parallel while the DMA2D is transferring data. If concurrent operation is
*   disabled, the CPU will wait everytime the DMA2D is active.
*   This feature is intended to limit the memory bandwidth, e.g. during display
*   update or other bandwidth consuming activities.
*
* ARGUMENTS:
*   aEnable - flag to switch on/off concurrent operation mode.
*
* RETURN VALUE:
*   None
*
*******************************************************************************/
void EwBspGraphicsConcurrentOperation( int aEnable )

This could help to avoid the memory bandwidth issue in certain situations. However, the graphical performance will go down.

Btw: What is the refresh rate of the display and the resulting pixel clock frequency? Have you checked that with AN4861 from ST?

The simplest and most helpful solution to halving the required memory bandwidth would be to use RGB565 instead of RGBA8888. Maybe a possibility?

Best regards,

Manfred.

Ask Embedded Wizard

Welcome to the question and answer site for Embedded Wizard users and UI developers.

Ask your question and receive answers from the Embedded Wizard support team or from other members of the community!

Embedded Wizard Website | Privacy Policy | Imprint

...