Program never leaves lv_timer_handler(); it stops at lv_timer_exec(lv_timer_t * timer)

Description

I am porting LVGL 9.0 to my dsPIC33CK project, it was tough to understand the huge library, but I think it was worth it, anyway, I have everything going well and compiled correctly but the screen never has anything displayed, after some digging, I found that when the MCU enters lv_timer_handler(); function, it will never go out, and after some debugging, I discovered that the problem is in the following line inside lv_timer_exec(lv_timer_t * timer) ,

if(timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer);

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

dsPIC33CK256MP206, MPLAB X V6.2, XC_DSC
16 bit parallel interface, ili9341, 320x240 px

What do you want to achieve?

I wish to display something, it was a long week with no achievements yet :smiling_face_with_tear:

What have you tried so far?

Make the heap bigger
Making the stack bigger
Navigating the very complex code with no evidence of what is happening

Code to reproduce

Here is the log until program stops doing anything useful

[User] (0.000, +0) main: ((Bismillah, a New Fresh Start)) main.c:58
[Info] (0.004, +4) lv_init: begin lv_init.c:139
[Info] (0.001, +1) lv_obj_create: begin lv_obj.c:100
[Trace] (0.005, +4) lv_obj_class_create_obj: Creating object with eac0 class on (nil) parent lv_obj_class.c:48
[Trace] (0.014, +9) lv_obj_class_create_obj: creating a screen lv_obj_class.c:57
[Trace] (0.021, +7) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.027, +6) lv_obj_constructor: finished lv_obj.c:349
[Info] (0.032, +5) lv_obj_create: begin lv_obj.c:100
[Trace] (0.036, +4) lv_obj_class_create_obj: Creating object with eac0 class on (nil) parent lv_obj_class.c:48
[Trace] (0.046, +10) lv_obj_class_create_obj: creating a screen lv_obj_class.c:57
[Trace] (0.054, +8) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.059, +5) lv_obj_constructor: finished lv_obj.c:349
[Info] (0.064, +5) lv_obj_create: begin lv_obj.c:100
[Trace] (0.069, +5) lv_obj_class_create_obj: Creating object with eac0 class on (nil) parent lv_obj_class.c:48
[Trace] (0.079, +10) lv_obj_class_create_obj: creating a screen lv_obj_class.c:57
[Trace] (0.086, +7) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.091, +5) lv_obj_constructor: finished lv_obj.c:349
[Info] (0.097, +6) lv_obj_create: begin lv_obj.c:100
[Trace] (0.101, +4) lv_obj_class_create_obj: Creating object with eac0 class on (nil) parent lv_obj_class.c:48
[Trace] (0.111, +10) lv_obj_class_create_obj: creating a screen lv_obj_class.c:57
[Trace] (0.118, +7) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.123, +5) lv_obj_constructor: finished lv_obj.c:349
[Info] (0.639, +516) lv_obj_create: begin lv_obj.c:100
[Trace] (0.643, +4) lv_obj_class_create_obj: Creating object with eac0 class on (nil) parent lv_obj_class.c:48
[Trace] (0.652, +9) lv_obj_class_create_obj: creating a screen lv_obj_class.c:57
[Trace] (0.659, +7) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.665, +6) lv_obj_constructor: finished lv_obj.c:349
[Info] (0.670, +5) lv_button_create: begin lv_button.c:50
[Trace] (0.675, +5) lv_obj_class_create_obj: Creating object with f07a class on 575e parent lv_obj_class.c:48
[Trace] (0.685, +10) lv_obj_class_create_obj: creating normal object lv_obj_class.c:81
[Trace] (0.693, +8) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.698, +5) lv_obj_constructor: finished lv_obj.c:349
[Trace] (0.703, +5) lv_button_constructor: begin lv_button.c:63
[Trace] (0.709, +6) lv_button_constructor: finished lv_button.c:68
[Info] (0.715, +6) lv_label_create: begin lv_label.c:83
[Trace] (0.720, +5) lv_obj_class_create_obj: Creating object with dbe4 class on 575e parent lv_obj_class.c:48
[Trace] (0.729, +9) lv_obj_class_create_obj: creating normal object lv_obj_class.c:81
[Trace] (0.737, +8) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.742, +5) lv_obj_constructor: finished lv_obj.c:349
[Trace] (0.747, +5) lv_label_constructor: begin lv_label.c:623
[Trace] (0.753, +6) lv_label_constructor: finished lv_label.c:650
[Info] (0.760, +7) lv_slider_create: begin lv_slider.c:68
[Trace] (0.764, +4) lv_obj_class_create_obj: Creating object with f362 class on 575e parent lv_obj_class.c:48
[Trace] (0.774, +10) lv_obj_class_create_obj: creating normal object lv_obj_class.c:81
[Trace] (0.782, +8) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.786, +4) lv_obj_constructor: finished lv_obj.c:349
[Trace] (0.792, +6) lv_bar_constructor: begin lv_bar.c:228
[Trace] (0.798, +6) lv_bar_constructor: finished lv_bar.c:249
[Info] (0.803, +5) lv_obj_create: begin lv_obj.c:100
[Trace] (0.807, +4) lv_obj_class_create_obj: Creating object with eac0 class on (nil) parent lv_obj_class.c:48
[Trace] (0.817, +10) lv_obj_class_create_obj: creating a screen lv_obj_class.c:57
[Trace] (0.825, +8) lv_obj_constructor: begin lv_obj.c:320
[Trace] (0.830, +5) lv_obj_constructor: finished lv_obj.c:349
[Trace] (0.835, +5) lv_timer_handler: begin lv_timer.c:65
[Trace] (0.840, +5) lv_timer_exec: calling timer callback: 39a lv_timer.c:298
[Trace] (0.847, +7) _lv_display_refr_timer: begin lv_refr.c:327
[Trace] (0.852, +5) lv_obj_update_layout: Layout update begin lv_obj_pos.c:301
[Trace] (0.862, +10) lv_obj_update_layout: Layout update end lv_obj_pos.c:304
[Trace] (0.867, +5) lv_obj_update_layout: Layout update begin lv_obj_pos.c:301
[Trace] (0.875, +8) lv_obj_update_layout: Layout update end lv_obj_pos.c:304
[Trace] (0.881, +6) lv_obj_update_layout: Layout update begin lv_obj_pos.c:301
[Trace] (0.888, +7) lv_obj_update_layout: Layout update end lv_obj_pos.c:304
[Trace] (0.895, +7) lv_obj_update_layout: Layout update begin lv_obj_pos.c:301
[Trace] (0.902, +7) lv_obj_update_layout: Layout update end lv_obj_pos.c:304
[Trace] (0.908, +6) lv_obj_update_layout: Layout update begin lv_obj_pos.c:301
[Trace] (0.915, +7) lv_obj_update_layout: Layout update end lv_obj_pos.c:304
[Trace] (0.922, +7) wait_for_flushing: begin lv_refr.c:1076
[Trace] (0.928, +6) wait_for_flushing: end lv_refr.c:1090

Hi, I am new to LVGL but I had a very similar issue with LVGL 9 on ESP32, (using FREERTOS as the LVGL OS configuration) that drove me crazy during the last days.
I went more in depth into the calling tree and found that I was stuck in the call tree:
lv_draw_buf_flush() →
lv_draw_dispatch_wait_for_request() →
lv_thread_sync_wait().

I was never receiving a notification from the task that was supposed to notify me (who is it?).

The solution was to use the NO_OS configuration and so to get rid of the lv_thread_sync_wait() function.

Are we missing something, maybe an initialization?

Looking forward to hear from you guys.

I had exactly the same problem,although I do not use dsPIC33CK.my code just the same as you,it hangs on if(timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer);

I’m using STM32F429IGT6 And one 800 * 480 LCD,and lvgl_v8.2

this problem perhaps because of this func:lv_disp_draw_buf_init,and here is my code

int main() {
... // other settings
    init();
    lv_obj_t* obj = lv_obj_create(lv_scr_act());
    lv_style_t style;
    lv_style_init(&style);
    lv_style_set_bg_color(&style,lv_color_hex(0xFF0000));
    lv_obj_add_style(obj,&style,0);
    //lv_obj_set_size(obj,LV_PCT(40),LV_PCT(20));
    //lv_obj_align(obj,LV_ALIGN_CENTER,0,0);
    
	while(1) {
		lv_timer_handler();
                HAL_Delay(5);
	} 
}
// uint8_t* dbuf;
uint8_t dbuf[80 * 1024]; // 2(RGB565) * 800 * 480 = 768KB,
// and lvgl recommended at least 1/10 screen sized.
// For convenience set 80KB instead of 76.8KB.
void init() {
    lv_init();

    lv_disp_draw_buf_init(&disp_buf,(void* )dbuf,NULL,80 * 1024);

    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = my_flush_cb;
    disp_drv.hor_res = 800;
    disp_drv.ver_res = 480;

    disp = lv_disp_drv_register(&disp_drv);
}

void __DrawPoint (uint32_t x,uint32_t y,lv_color_t color) {
	uint32_t tar = ocram_base + \
	((uint32_t )y * 800 + x) * 2;
	*((uint16_t*)tar) = color.full;
}
void my_flush_cb(lv_disp_drv_t * disp_drv, 
const lv_area_t * area, 
lv_color_t * color_p) {
    //printf("x1,x2:%d,%d\n",area->x1,area->x2);
    //printf("y1,y2:%d,%d\n",area->y1,area->y2);
    for(int y = area->y1;y <= area->y2;y++) {
        for(int x = area->x1;x <= area->x2;x++) {
            __DrawPoint(x,y,*color_p);
            color_p++;
        }
    }
    lv_disp_flush_ready(disp_drv);
}

of course,two debug printf:

// lv_timer.c  line 300 static bool lv_timer_exec(lv_timer_t * timer)
if(lv_timer_time_remaining(timer) == 0) {
        /* Decrement the repeat count before executing the timer_cb.
         * If any timer is deleted `if(timer->repeat_count == 0)` is not executed below
         * but at least the repeat count is zero and the timer can be deleted in the next round*/
        int32_t original_repeat_count = timer->repeat_count;
        if(timer->repeat_count > 0) timer->repeat_count--;
        timer->last_run = lv_tick_get();
        TIMER_TRACE("calling timer callback: %p", *((void **)&timer->timer_cb));
            printf("ddddddebug11\n");
        if(timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer);
            printf("ddddddebug22\n");
        TIMER_TRACE("timer callback %p finished", *((void **)&timer->timer_cb));
        LV_ASSERT_MEM_INTEGRITY();
        exec = true;
    }

the problem is:the last para of lv_disp_draw_buf_init is the pixel count of the two buf,so There is an error in the code above,it should be lv_disp_draw_buf_init(&disp_buf,(void* )dbuf,NULL,80 * 1024 / 2);
fix it and rebuild,I got the right display.

this problem probably because memory access exceeds limit,with a 80KB array,the gcc compile shows that I’ve been use 150KB RAM(STM32F429IGT6 only has 192KB RAM,do not include CCMRAM).
so if you do not write that ‘/2’ ,I guess lvgl perhaps access an address out of bound.

then I test the code below

uint8_t* dbuf;
// uint8_t dbuf[80 * 1024];
void init() {
    dbuf = (uint8_t* )((uint32_t)ocram_base + 2 * 1024 * 1024); 
    // the low 2MB is using by LTDC
	lv_init();

    lv_disp_draw_buf_init(&disp_buf,(void* )dbuf,NULL,512 * 1024);
...

I have one SDRAM on my develop board(W9825G6KH-6,256MB),ocram_base is the start address of SDRAM,and the test’s result shows everything ok.as you can see,this time I use 512K but not exceeds(512K < 256M).

so check your lv_disp_draw_buf_init,perhaps solve the problem.