LVGL not calling flush_cb despite calling lv_tick_inc and lv_timer_handler

Description

I’ve got LVGL running on an FreeRTOS application, with vApplicationTickHook calling lv_tick_inc(1);.
In a display task I’ve got a while(1), calling lv_timer_handler() and a delay every 5ms.
When loading a new screen (load all objects and then call lv_scr_load()), nothing happens. The flush_cb is not called anytime. Using LV_USE_LOG 1 I can see the objects are malloc’d.

Note that the very first screen that is loaded right after lv_init() and init_display() is working. See the code snippet below.

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

A custom board with an RT i.MX 1011. Compiling using the arm compiler from MCUXpresso

What do you want to achieve?

I’d like to be able to switch screens.

What have you tried so far?

Increasing LVGL heap size, increasing FreeRTOS heap size and increasing the stack size of the task that calls lv_timer_handler(). Also first the lv_ui object was first inside the task declared, changing it to a static global variable did no change.

Code to reproduce

Add the relevant code snippets here.


static lv_ui guider_ui;    //<-- using a global lv_ui object

static void update_display_task(void *pvParameters){
        //Some clock settings for the peripheral.

	set_screen_t screen_sel;

	lv_init();
	init_display();           //<-- initialise the display 
	setup_ui(&guider_ui);      //<-- here a display is loaded 
	events_init(&guider_ui);      //<-- empty function (no events apply yet)
	init_display_screens(&guider_ui);         //<-- setup an array containing all screens so setup_screen can call them. 
#if LV_USE_LOG
	lv_log_register_print_cb(print_from_lvgl);
#endif
	//Turn on backlight
	GPIO_PinWrite(BOARD_INITPINS_LCD_B_PERIPHERAL, BOARD_INITPINS_LCD_B_CHANNEL, 1);

	while(1){
		//Update display here (read from queue, update display)
		if(xQueueReceive(screenQueue, &screen_sel, 1 / portTICK_PERIOD_MS)){
			setup_screen(&guider_ui, screen_sel.screen);
		}
		lv_timer_handler();
		vTaskDelay(5 / portTICK_PERIOD_MS);
	}
}

//This is called from the systick ISR every 1ms
void vApplicationTickHook(void){
	lv_tick_inc(1);
}

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf_1[MY_DISP_HOR_RES * 10];
void init_display() {

	//Initialise display driver

	lv_disp_draw_buf_init(&disp_buf, buf_1, NULL, MY_DISP_HOR_RES * 12);
	lv_disp_drv_init(&disp_drv);
	disp_drv.draw_buf = &disp_buf;
	disp_drv.hor_res = 160;
	disp_drv.ver_res = 128;
	disp_drv.flush_cb = write_display;
	disp_drv.clean_dcache_cb = my_clean_dcache_cb;
	lv_disp_t *disp = lv_disp_drv_register(&disp_drv);
        //Setup hardware peripherals and setup display correctly here
}

Thanks for any help on this matter.

Marcel

Haha :slight_smile:

While copying code snippets I saw the lv_disp_draw_buf_init() function being passed MY_DISP_HOR_RES * 12 as buffer size, but the buffer size was actually smaller (MY_DISP_HOR_RES * 10). Changing this fixed the issue.

I thought I’d update this so maybe someone else could find and recognize this issue.

Anyway, thanks.

Marcel