LVGL stops running,but the system is running normally

Description

Hi,
the following is my description of the problem, I hope everyone can help to solve this problem, thank you very much.
My project is about streaming media, one of the features is to view the file list.But I meet a problem when I operate list A to list B:
I‘m repeatedly deleting and creating a list, and repeatedly changing the text content of the buttons in the list.
When I repeat this operation to the 91st time.lv_task_handler stopped working because there is no more print information.But the system is running normally.

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

Arm+Linux LVGL:7.0.5

What do you experience?

I tested it about 8 times, and there was no response at the 91st time.At the same time, the CPU usage has become 100%(Usually takes up 4%). But what I am doing is repetitive.

What do you expect?

I hope to solve or avoid this problem

Code to reproduce

I made a simplified version of the demo.During the board test, the mode is switched once about 5s

int file_totalnum = 0;
int file_current_page = 1;
int file_total_page = 1;
int mode = 1, file_foucus_pos = 0;
lv_obj_t * label_mode;
lv_obj_t * pblist_cont;
lv_obj_t * pblist_list;
lv_obj_t * pblist_btn[10];
static lv_style_t style_cont2;

static int gui_obj_enable(lv_obj_t * obj, bool en)
{
	//if (obj == NULL)return -1;
	if (en == 1)lv_obj_set_hidden(obj, 0);
	else if (en == 0)lv_obj_set_hidden(obj, 1);
	else lv_obj_set_hidden(obj, 1);
	return 0;
}

static void test(void)
{
	lv_obj_t * title_cont = lv_cont_create(lv_scr_act(), NULL);
	lv_obj_set_size(title_cont, 320, 30);
	lv_obj_set_pos(title_cont, 0, 0);

	lv_style_init(&style_cont2);
	lv_style_set_bg_opa(&style_cont2, LV_STATE_DEFAULT, LV_OPA_0);//LV_OPA_0
	lv_style_set_bg_color(&style_cont2, LV_STATE_DEFAULT, LV_COLOR_RED);

	lv_obj_add_style(lv_scr_act(), LV_BTN_PART_MAIN, &style_cont2);// 

																   /*Mix text and symbols*/
	label_mode = lv_img_create(title_cont, NULL);
	lv_obj_set_pos(label_mode, 5, 5);
	lv_img_set_src(label_mode, LV_SYMBOL_VIDEO);
	//lv_label_set_text(g_GUI.title.obj.label_mode, LV_SYMBOL_VIDEO);

	lv_obj_t * label_time = lv_label_create(title_cont, NULL);
	lv_obj_set_pos(label_time, 94, 8);
	lv_label_set_text_fmt(label_time, "%s", "07/23 15:33:30");
	gui_obj_enable(label_time, 1);


	pblist_cont = lv_cont_create(lv_scr_act(), NULL);
	lv_obj_set_size(pblist_cont, 320, 210);
	lv_obj_set_pos(pblist_cont, 0, 30);

	lv_obj_t * pblist_title = lv_label_create(pblist_cont, NULL);
	lv_obj_set_pos(pblist_title, 10, 2);
	lv_label_set_text_fmt(pblist_title, "%s", "Files:");

	lv_obj_t * pblist_filepage = lv_label_create(pblist_cont, NULL);
	lv_obj_set_pos(pblist_filepage, 10, 190);
	lv_label_set_text_fmt(pblist_filepage, "%s%d/%d", "Page:", file_current_page, file_total_page);

	lv_obj_t * pblist_filenum = lv_label_create(pblist_cont, NULL);
	lv_obj_set_pos(pblist_filenum, 230, 190);
	lv_label_set_text_fmt(pblist_filenum, "%s%d", "Total:", file_totalnum);

	gui_obj_enable(pblist_cont, 0);
}

static void change_mode(int mode)
{
	int i;
	if (mode == 2)//mode A
	{

		file_totalnum = 6;//for test
		file_foucus_pos = 0;

		pblist_list = lv_list_create(pblist_cont, NULL);
		lv_list_set_scroll_propagation(pblist_list, 1);
		lv_list_set_scrollbar_mode(pblist_list, LV_SCROLLBAR_MODE_DRAG);
		lv_list_set_anim_time(pblist_list, 0);
		lv_obj_set_size(pblist_list, 320, 170);
		lv_obj_set_pos(pblist_list, 0, 20);

		for (i = 0; i < 10; i++)
		{
			pblist_btn[i] = lv_list_add_btn(pblist_list, NULL, " ");//10 files per page
		}

		//gui_update_playback_listbtn(RECORD_FILE_TYPE_VIDEO);//update playback list

		gui_obj_enable(pblist_cont, 1);
	}
	else if (mode == 3)//mode B
	{
                //This mode will change the text content of each button in the list, and do get and set operations
		file_totalnum = 5;//5 for test 
		file_foucus_pos = 0;

		//gui_update_playback_listbtn(RECORD_FILE_TYPE_PHOTO);//update playback list
	}
	else if (mode == 1)//mode C
	{
		gui_obj_enable(pblist_cont, 0);

		if (file_totalnum != 0)
		{
			lv_obj_clean(pblist_list);
		}
	}
}

int mode_test=0;
int main(int argc, char** argv)
{

    lv_init();
    hal_init();
   test();

    while (1) {
		mode_test++;
		if (mode_test > 3)mode_test = 1;
		change_mode(mode_test);

        lv_task_handler();
        Sleep(5);     
    }

Screenshot and/or video

Usually stopped on this interface, This interface would have refreshed the content in the list.

Hi @real23355 ,

Your while() loop in main has too longer sleep time to give you a workable solution. Depending on your system performance I would call lv_task_handler() somewhere between every 10 and 50mS. You either need to create a static counter in main to trigger the mode change or create an lv_task as I have described here, this link explains how to structure your code to deal with events with out blocking the system processing, which also applies to your scenario.

A quick solution using a static counter would be something like this:

int mode_test=0;
int main(int argc, char** argv)
{
    static uint32_t timer;
    lv_init();
    hal_init();
    test();

    while (1) {
        if( timer++ > 100 )  {    // Do this every 5 seconds
	        mode_test++;
		    if (mode_test > 3)mode_test = 1;
		    change_mode(mode_test);
            timer = 0;
        }
        lv_task_handler();   //  Always call lv_task_handler() every ~50mS to keep GUI responsive
        usleep(50000);     
    }
}

I hope that is helpful.

Kind Regards,

Pete

Another thing to try is updating to LVGL 7.4, which might already have a fix for this problem.

Thanks for the help.
This demo is problematic on lv_task, in my thread,I used it like this:

lv_tick_inc(10);
lv_task_handler();
usleep(10*1000);

I adjusted the time between 10ms to 100ms,This problem will still occur.
Is it right to trigger like this?
thanks!

Don’t call lv_tick_inc and lv_task_handler in the same loop. One should be called in another thread or an interrupt handler. Or, if your platform already tracks milliseconds since startup, you can configure LV_TICK_CUSTOM in lv_conf.h.

I downloaded the latest code for testing yesterday,but still has the problem.

I will put lv_tick_inc in another thread to test it, thanks for the help.

Now,I I separated lv_tick_inc and lv_task_handler in two threads,but still has the problem.

loopA:
lv_task_handler();
usleep(50*1000);

loopB:
lv_tick_inc(5);
usleep(5*1000);

I have considered whether it is related to memory, etc., but I have 68M remaining available memory.

At the same time, there will be other operations to switch menus in my system, but these operations are very stable. So is this question related to lv_list_create , lv_obj_clean or lv_obj_set_hidden(I will hide some buttons of list that are not used temporarily)?

loopA should still run at a 5-10 ms frequency.

If you are calling LVGL APIs from another threads, make sure you are guarding API calls with a mutex (the sole exception is lv_tick_inc, which should not be guarded).

I tried to add a mutex in the code,but it seems to have no effect.And today I rechecked the print message. I found this print message when LVGL went wrong
Warn: Couldn't allocate memory (lv_mem.c #203 lv_mem_alloc()
and I also find the print in Visual Studio.


Is it caused by this?
Thanks for help!

Yes; that means that either your heap is not big enough, or there is memory corruption somewhere. Let’s hope it’s the first one. :slightly_smiling_face:

If you have LV_MEM_CUSTOM enabled, you need to find out how to increase your heap size. If LV_MEM_CUSTOM is disabled, you can just increase LV_MEM_SIZE.