Strange error (not enought memory)

Description

Hello. I am using ESP32 with 4.3 inch display (resolution is 272x480, but it does not matter) and sometimes it hangs with LVGL 8.3.
I am making the chat (like WhatsApp or Telegram). My design has 2 screens (users and messages, switching goes with animation) and each message is an object with label and icon inside. The message appears with short animation and when I want to load 40 or more messages, the board hangs. Sometimes, if I load 20-30 messages and type another one (use keyboard object and type a lot of letters), the board hangs too.
What’s the matter? ESP do not send any errors to Serial port.
Maybe there is a problem with allocating memory? I do not know what this code does, but maybe there is a problem:

        #ifdef ESP32
            disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth *screenHeight/10, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
        #else
            disp_draw_buf = (lv_color_t *)malloc(sizeof(lv_color_t) * screenWidth * screenHeight/10);
        #endif
        lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight/10);

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

ESP32

What LVGL version are you using?

8.3

I went to settings and found out properties that switch on checking memory.
On the screen thhere is written that program uses about 50% of memory, but sometimes hangs…

It’s really less information you provide here.
Problems within your app can be anything.
The code you provided should only be called once, and in this case it shouldn’t be any problem (as you wouldn’t see anything)…

If you do not know what memory allocation (and freeing!) is good for, and how it is used, just read the docs :wink:

[robekras], which docs?
Of course I know about functions malloc/free in Arduino/C++, but does not when saying about LVGL library functions. Unfortunatelly, ESP does not print any errors/warnings.
I tried to increase or decrease size of memory which heap_caps_malloc() allocate, but nothing happen.
As I understood, heap_caps_malloc is the buffer of the frame and we can allocate memory for the full display size(sizeof(lv_color_t) * screenWidth * screenHeight); but it will not solve the problem.

Again, lv_disp_draw_buf_init is (should be) only called once, when setting up (initializing) the lvgl environment.
The disp_draw_buf is not (and doesn’t need to be) the full display frame size.
It’s in general only a small part of the full display’s frame size. This buffer is only the working buffer for lvgl.
If lvgl needs the update the full display, it does it in parts.
In the flushing function this working buffer is copied to the real display (frame buffer) which is connected with SPI to the ESP32.
The call of lv_disp_draw_buf_init (and the entire lvgl initialization) seems to be ok, else you would not see anything on display.

The problem seems to be located within your application code which manages the switching to the different screens and handling of the ‘messages’.
And this can be anything. E.g. wrong pointer handling, buffer overflow when using string functions, infinite loops etc.

[robekras], you are absolutelly right: the problem is not with allocating the memory because it allocates only 1 time in setup section. There can be an error only when some transistors don’t work, but, I don’t believe in it.
The problem is not in my sketch too, because problem appears when I just type letters on keyboard (LVGL’s component) and looks like infinitive loop - no errors, just hanging…
Maybe I need to do something with settings in lvgl configuration file…

I’m not sure whether I correctly unterstand you:
Seeing a problem when you type a character on keyboard doesn’t necessarily mean, that the problem is related to the typing function.
When your code does something wrong, e.g. writing to a wrong memory location, than the problem (exception, infinite loop or anything else) might occur at a very different time.
I do not know your code, but I don’t think it’s a problem of configuring lvgl nor is it a problem of lvgl.
As I understand it, the app is working for a while, and after some processing, it fails (what ever that means).
With a problem in configuring lvgl, you wouldn’t see anything. It wouldn’t work from the very beginning.
As I don’t think that your app does need too much resources, my guess is again, your code does something wrong.

When I click the keyboard’s button, nothing interesting appears:

// --------------------------------------------- обработка нажатия клавиши на клавиатуре ---------------------------------------
void cb_keyboard(lv_event_t * e){
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED){                                                   // надо попробовать LV_EVENT_VALUE_CHANGED
        uint16_t bt = lv_keyboard_get_selected_btn(keyb);
        //Serial.println(bt);
        if (bt == 12){
            //Serial.println("backspace");
            lv_textarea_del_char(message_text_input);
        }
        else if (bt == 24){
            //Serial.println("Enter");
            lv_textarea_add_char(message_text_input, '\r');                         // если не переносит - заменить на \n
        }
        else if (bt == 25){
            //Serial.println("Shift");
            if (lv_keyboard_get_mode(keyb) == LV_KEYBOARD_MODE_USER_1){
                lv_keyboard_set_map(keyb, LV_KEYBOARD_MODE_USER_2, kb_ru_big, matrix_ru_big);
                lv_keyboard_set_mode(keyb, LV_KEYBOARD_MODE_USER_2);
            } else if (lv_keyboard_get_mode(keyb) == LV_KEYBOARD_MODE_USER_2){
                lv_keyboard_set_map(keyb, LV_KEYBOARD_MODE_USER_1, kb_ru_small, matrix_ru_small);
                lv_keyboard_set_mode(keyb, LV_KEYBOARD_MODE_USER_1);              
            }

            
        }
        else if (bt == 38){
            //Serial.println("rus/eng");

        }         
        else if (bt == 46){
            //Serial.println("123");
            lv_keyboard_set_mode(keyb, LV_KEYBOARD_MODE_SPECIAL);                   //LV_KEYBOARD_MODE_NUMBER
        } 
        
        
        else{
            const char * txt = lv_keyboard_get_btn_text(keyb, bt);
            lv_textarea_add_text(message_text_input, txt);
            
        }
    }
}

but application hangs…

I found the reason. In configuration file I changed memory settings lika that

#if LV_MEM_CUSTOM == 0
    /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
    #define LV_MEM_SIZE (96U * 1024U)          /*[bytes]*/

And now everything works great! No hangs!
But, finding the way to correct is only the 1st part. The main part is find the reason why it did not work with LV_MEM_SIZE (48U * 1024U) //48 KBytes

After increasing LV_MEM_SIZE program does not hang when loading/displaying/animating messages, but sometimes does when typing long message. Too strange…

Do you use malloc and free in your program?
Do you use string functions like sprintf, strcpy, strcat in your program?
Do you do pointer arithmetic?

As far as I can see, your program isn’t doing that much, as your heap memory is running out.
A different (changed) memory layout can also lead to a different error appearance.

  1. I do not use malloc except 1 string which requires LVGL (I wrote it here earlier).
  2. I do not use String because it needs much memory. I use (sorry, I don’t know the correct english name) array of chars and such functions as memset, strcpy, strcat, strcmp…
  3. Sometimes, but…only to find out the next symbol in array of chars.
  1. Sorry could not find your post where you use malloc for a string. Do you mean the malloc for disp_draw_buf? That was not for a string buffer (aka char*). That’s the drawing buffer.

  2. I do not mean String but string functions. Don’t use strcpy, strcat. Use always the better functions with ‘n’ like strncpy, strncat.

  3. Shouldn’t be a problem as long as you only read.

Maybe a hint: When you use utf8, have in mind, that the number of utf8 characters (in an utf8 string) is not the same as you need for storing it in char buffer. This means if you have five letters in Cyrillic you need at least (5 * 2) + 1 for your char buffer.

Not for the string. I do not use String.
Earlier you asked about malloc() function, not malloc of the string

Yes

disp_draw_buf = (lv_color_t *)malloc(sizeof(lv_color_t) * screenWidth * screenHeight/10);

Thanks. But… I use them when get something from UART. Here I do not receive UART, just type on the screen

Do you process the input that you typed in, e.g. after you hit enter?

When I type, I process like this Strange error (not enought memory) - #8 by cafetera
And after clicking “send” button I process the whole message - generate ID, add sender’s name and so on…

Yes, I know your cb_keyboard.
It doesn’t look any special there.

I’m more interested in the function

I process the whole message - generate ID, add sender’s name and so on…

When the function cb_keyboard ‘hangs’, it doesn’t necessarily mean that the problem is in the cb_keyboard.
It can be on a very different place!

This function works when I press “send” button, so, don’t think of it. The problem occurs when I just type on the keyboard.
Probably I found 1 reason. I think the problem occurs when I click on the little space between the buttons.