Skip to content

Conversation

@rondlh
Copy link

@rondlh rondlh commented Sep 15, 2025

Prevent background loop starvation by splitting long graphical tasks causing serial buffer underruns.
Target is to split the graphical tasks into slices of max 1ms.

Description

This PR gives solves the issue of background loop starvation causing buffer underruns.
The TFT application is split into 2 parts, a the foreground and backend loop. The foreground loop handles graphical processes which are not very time critical. The backend loop handles critical processes like serial data receiving and sending. The processor is single threaded, there is not multitasking at all. The application uses interrupt, which helps to make sure serial data is received and send, but if the data is not processed rapidly then a buffer underrun can occur very fast. I did some benchmarks to illustrate this on my BTT TFT35 V3.01
GUI_ClearPrect(&terminalAreaRect[0]); Takes about 20ms
GUI_ClearPrect(&editorAreaRect[1]); Takes about 16ms
The following code takes about 90ms

  for (uint8_t i = GKEY_SEND; i < COUNT(gcodeKey123); i++)  // draw all the visible keys (text box keys are skipped)
  {
    keyboardDrawButton(i, false);
  }

And worse of all, in the terminal there are processes that can take over 1 second without giving attention to the background loop.

In Configuration.h I found this comment:
// NOTE: This may slow down graphics while switching menus while printing.
#define RAPID_SERIAL_COMM // Default: uncommented (enabled)

This option should definitely be enabled (is default). Bench marking shows that the background loop can be executed over 100.000 times a second. So I would not worry too much about giving more attention to it.

I bench marked the code changes I made in this PR and could not find any difference in the required time needed to execute the graphical processes.

Benefits

Improve overall data receive and send responsiveness.
Reduces or possibly even eliminates the chance of a serial buffer underruns.
No measurable negative affect on graphical performance.

Related Issues

#2994

Prevent background loop starvation by splitting long graphical task.
Target is to split the graphical tasks into slices of  max 1ms.
Update LCD_SetWindow after background loop call to prevent drawing artefacts
@rondlh rondlh marked this pull request as draft September 20, 2025 23:12
Fix graphical artefact in notifications, still WIP
Fix graphic corruption in notifications.
Why is this needed?
Are notification drawn inside the ISR?
…cationHandler()

Use variable names x0, y0, x1, y1
sx -> x0
sy -> y0
ex -> x1
ey -> y1

Some places used x1 and x2 instead of x0 and x1.
Some function are only different in the color they draw.
Removed notificationHandler, it calls the loopFrontEnd from theloopBackend. Let the loopFrontEnd handle it.
…ionHandler()

Also remove the notificationHandler variable after removing notificationHandler()
Remove incorrectly added "!" from code, this also helps to keep the code that is affected by the timer rollover PR the same so merging is easier.

"_toastAvailable == false" <==> "toast available is false"
is the same as
"!_toastAvailable" <==> "not toast available"
Prevent running loopBackEnd before everything is ready, this can happen from the graphic routines that give time to loopBackEnd
…of defined rows are drawn

Yield after a number of defined pixels are drawn, not after a number of defined rows are drawn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant