ESP32-S3 + Arduino = fatal rendering error

Description

What MCU/Processor/Board and compiler are you using?

ESP32-S3, Arduino IDE 2.3.5, esp32 3.2.0

What LVGL version are you using?

9.2.2

What do you want to achieve?

LVGL apps that run vitthout crashing.

What have you tried so far?

See below

Code to reproduce

Several full-size apps which all crash sooner (immediately) or later (after a few minutes or hours) with -

lv_inv_area: Asserted at expression: !disp->rendering_in_progress (Invalidate area is not allowed during rendering.) lv_refr.c:274

These same apps all used to work OK.
I have been unable to isolate any one thing that causes this error.
However, it is usually either a call to -

  lv_label_set_text(label, txt);

or

 lv_obj_set_style_bg_color(obj, lv_color_hex(col), LV_PART_MAIN);

Here’s my LVGL init -

static uint32_t tick_cb(void) {
  return millis();
}

void ARDUINO_ISR_ATTR wait_cb(lv_disp_t* disp) {
  lv_disp_flush_ready(disp);
}

void LVGLinit() {
  sprintf(Lbuf, "LVGL init v %d.%d.%d", lv_version_major(), lv_version_minor(), lv_version_patch());
  Log(Lbuf, INFO);

  lv_init();
  lv_tick_set_cb(tick_cb);

  disp = lv_display_create(TFT_WIDTH, TFT_HEIGHT);
  lv_display_set_flush_cb(disp, DisplayFlush);
  lv_display_set_flush_wait_cb(disp, wait_cb);

  int drawBufSize = TFT_WIDTH * TFT_HEIGHT * 2;
  static void* buf0 = (lv_color_t*)heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);
  static void* buf1 = (lv_color_t*)heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);
  lv_display_set_buffers(disp, buf0, buf1, drawBufSize, LV_DISPLAY_RENDER_MODE_PARTIAL);
...
}

void DisplayFlush(lv_display_t* disp, const lv_area_t* area, unsigned char* data) {
  uint32_t w = lv_area_get_width(area);
  uint32_t h = lv_area_get_height(area);

  lv_draw_sw_rgb565_swap(data, w * h);
  gfx.pushImage(area->x1, area->y1, w, h, (uint16_t*)data);

  // Not needed - handled instead by lv_display_set_flush_wait_cb()
  // lv_disp_flush_ready(disp);
}

Are you sure? You miss here completely.

According to @Kisvegabor -

Is calling lv_display_flush_ready still needed?

No, you can use either the lv_display_flush_ready or the flush_wait_cb.

UPDATE
After further Googling I read that using double buffers of -

heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);

does NOT use DMA. And without DMA only one buffer is needed, and .lv_display_set_flush_wait_cb() is NOT needed.
So I made those changes, but still get the error.

Somehow LVGL object updates are being called while flushing is underway.

I can’t believe that I’m the only person getting this error, but Google can’t find any others…

Well, I’ve managed to get it to run for a day now.
The errors started after updating a few non-LVGL Arduino libraries.
This is LVGL code that used to run correctly, despite some rather bad coding.
Fixing the bad code, and removing Alarm.delay calls between LVGL updates improved things a bit, but the error still happened fairly quickly.
Finally I write a function to test if LVGL was ‘flushing’ or ‘rendering’, and if so, discard that update attempt.
Every update command is now enclosed by this test function.

#include <lvgl.h>
#include <C:/Users/Hamish/Documents/Arduino/libraries/lvgl/src/display/lv_display_private.h>
#include <C:/Users/Hamish/Documents/Arduino/libraries/lvgl/src/core/lv_refr.h>
#include <C:/Users/Hamish/Documents/Arduino/libraries/lvgl/src/core/lv_refr_private.h>

bool LvReady() {
   lv_display_t* disp_refr = lv_refr_get_disp_refreshing();

   if (disp_refr != NULL) {
      if (disp_refr->flushing)
        Serial.println("FLUSHING");
      else if (disp_refr->rendering_in_progress)
        Serial.println("RENDERING");
      else
        return true;
   }

   return false;
}

void LvSetLabel(lv_obj_t* obj, int val) {
  if (LvReady() && obj)
    lv_label_set_text_fmt(obj, "%d", val);
  else
    Serial.println(" set label")
}

And what is question? Only my crystall ball say you start more as one thread and call lv here. Then read docu about LVGL isnt thread safe…

Hi Mariam,
My question is how to avoid the error I have recently started getting -

lv_inv_area: Asserted at expression: !disp->rendering_in_progress (Invalidate area is not allowed during rendering.) lv_refr.c:274

I know what it means, but do not know how to avoid it.
And yes, I have RTFM.

Threading Considerations — LVGL 9.3 documentation

Thanks for the link, I had already read this when trying to find a fix for the error.
It makes for difficult reading because -
a) I am using the Arduino IDE.
b) I’m not a computer science graduate.

Have in your code or used libs xTaskCreate?
Show loop code or better all relevant code.

Thanks, I’ll read up on that.
The whole project is several thousand lines of code (which used to work OK)

void loop() {
  lv_timer_handler();
  Alarm.delay(1);
}

static uint32_t tick_cb(void) {
  return millis();
}

void LVGLinit() {
  lv_init();
  lv_tick_set_cb(tick_cb);
...