Lv_task_handler execution time

I am facing to some issue with poor display response and seeking for some help. So I will be very pleased if someone could help.

I am using lvgl 7.2.0, freeRTOS 10.3.1 on S32K148 MCU.

Problem explanation. I am using old monochromatic LCD display with resulotuin 320x240 px with only GPIO interface, there is no way to control it via I2C, SPI etc. And when I touch some button it takes about 400ms to change button background. I have discoverd that from some reason it is stuck in lv_task_handler() in worst case for 2500 ms (this time was catch during whole screen refresh and I also measure actual LCD driver write secuence which was about 150ms). I call lv_task_handler() each 1ms in same task first is called lv_task_handler then lv_tick_inc then freeRTOS delay.

Measurement of lv_task_handler() was done with freeRTOS contex switch off and I set some spare MCU pin on and after lv_task_handler off.

Next I notice that in one lv_task_handler() it can call multiple LCD driver write.

So do you have any idea what can cause such a long execution of lv_task_handler.


Multiple calls to your driver are expected. Depending on your configuration, it sometimes splits rendering into chunks that need to be flushed to the display individually. For example, if your configured buffer size is 1/10 of the display size, it will call the driver function 10 times. It doesn’t redraw the same tenth of the display multiple times though.

150ms for a single display write sequence is very slow. That means your maximum theoretical frame rate is 6 frames a second (which will look very choppy).

You should not be calling lv_task_handler and lv_tick_inc in the same task. On a slow system, this will always cause problems (and it frequently will on fast systems as well). Call lv_tick_inc from a timer interrupt or another task, and decrease the frequency of the lv_task_handler task to 10ms.

Ok, thanks I will try to call ‘lv_task_handler’ from timer ISR.

And yes display is very slow, but I do not need high fps. Target application displays some temperatures, time, error flags etc. and this works fine. But problem is when user wants to go to menu, he touches the button and after cca 400ms it starts doing something, similar is numeric input via keyboard for example in time setting. Users are confused when they touches button and nothing happened and they don’t know if they touch button or missed and touch again then it counts both touches eg. 11 and user wants 16 …

Also we have old platform based on 8bit MCU 16MHz with our very basic graphic library compared to lvgl and it works just fine.

So it is possible that execution of ‘lv_task_handler’ can take eg. 1s? And reason for that can be small output buffer resulting in more LCD writes?

‘lv_task_handler’ dosn’t use wait functions with timeout or something which can delay execution?

lv_task_handler should not be called from a timer ISR; lv_tick_inc should be.

lv_task_handler never waits for anything except your display driver; slow execution means that either LVGL is running slowly or that the display is slow.

So I have some updates. I move lv_tick_inc to systick handler and it improve performace a lot. So thanks.

Now I am trying to improve it even more. According to this article and documentation how should I set size_in_px_cnt in function lv_disp_buf_init? I am little bit confused.

My settup is LV_HOR_RES = 320, LV_VER_RES = 240, monochromatic LCD so LV_COLOR_DEPTH = 1. I set my buffer size to (LV_HOR_RES * LV_VER_RES) / 8 because horizontal pixes are grouped. And now what to set as size_in_px_cnt? In examples from article and documentation mention above it looks like it should be set as buffer size so size_in_px_cnt = (LV_HOR_RES * LV_VER_RES) / 8 but description in documentation says it should be pixel count which is LV_HOR_RES * LV_VER_RES. So what is corret?