Flush_cb()does not called when lv_task_handler() run

Description

when i porting LVGL to my project,i test with example code,but Flush_cb() can’t be called.

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

THM3682FAQD

What LVGL version are you using?

V7.10.0

What do you want to achieve?

i just want to test LVGL and display “hello word” on LCD screen.

What have you tried so far?

i tried sample code on lvgl website

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

/*You code here*/

void task()
{
lv_init();
hal_init();
lv_demo();
while()
{
lv_task_handler();
lv_tick_inc(10);
sleep(100);
}
}
static void hal_init()
{

//disp_init();
lv_disp_buf_t draw_buf_dsc_1;                    /*A buffer for 10 rows*/
lv_color_t draw_buf_1[1024];
lv_disp_buf_init(&draw_buf_dsc_1, draw_buf_1, NULL, 1024);   /*Initialize the display buffer*/

lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

/*Set up the functions to access to your display*/

/*Set the resolution of the display*/
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;

/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = Flush_cb;

/*Set a display buffer*/
disp_drv.buffer = &draw_buf_dsc_1;

#if LV_USE_GPU
/Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)/

/*Blend two color array using opacity*/
disp_drv.gpu_blend_cb = gpu_blend;

/*Fill a memory array with a color*/
disp_drv.gpu_fill_cb = gpu_fill;

#endif

/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);

}
volatile u8 *FrameBuffer = (u8 *)0x2003C000;
static void Flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
u32 y;
u32 x;

for(y = area->y1; y <= area->y2 && y <disp_drv->ver_res; y++)
{
    for(x = area->x1; x <= area->x2; x++) 
    {
        //pDisp[y *disp_drv->hor_res + x] = (u32)lv_color_to32(*color_p);
        FrameBuffer[y *disp_drv->hor_res + x] = (u32)lv_color_to32(*color_p);
        color_p++;
    }

}

lark_lcd_write(LCD_NORMAL,area->x1, area->y1, x, y, FrameBuffer);//my lcd driver function
lv_disp_flush_ready(disp_drv);

}
static void lv_demo()
{
lv_obj_t * scr = lv_disp_get_scr_act(NULL);
lv_obj_t * label1 = lv_label_create(scr, NULL);
lv_label_set_text(label1, “Hello\nworld”);
lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);
}

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

What’s your stack size and how is the LVGL heap configured?

i replace malloc and free to my systerm function in lv_conf.h
stack size >8kb and Dynamic data (heap) >16kb
when i enable LVGL log output, it executed _lv_disp_refr_task(), lv_refr_areas(),but does not call Flush_cb()
would you please share some suggestions?

I can’t think of anything off the top of my head - perhaps try stepping through lv_refr_areas.

does i need implement set_px_cb()?i used one buffer

No; flush_cb should be all you need.

Are you using a custom heap?

yes,i used custome heep and register my function into lv_conf.h

Check that you’re not running out of heap space; that will usually cause LVGL to just freeze.

how to ouptput LVGL heap used detail?

from my side,i register function to use heap.if alloc() or free() fail.system will prompt warning.i can output my system log

when i set lv_tick_inc(100),Flush_cb() called.but display is wrong.


correct display:

my Flush_cb() code:

static void Flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
TRACE(DBG_TRACE_LVL,"%s—>\r\n",FUNCTION);
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_coord_t hres = disp_drv->rotated == 0 ? disp_drv->hor_res : disp_drv->ver_res;
lv_coord_t vres = disp_drv->rotated == 0 ? disp_drv->ver_res : disp_drv->hor_res;
TRACE(DBG_TRACE_LVL,"%s—>area->x2=%d area->x1=%d area->y1=%d area->y2=%d hres=%d vres=%d rotated=%d\r\n",FUNCTION,area->x2,area->x1,area->y1,area->y2,hres,vres,disp_drv->rotated);
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1)
{
lv_disp_flush_ready(disp_drv);
return;
}

u32 y;
u32 x;
for(y = area->y1; y <= area->y2 && y <disp_drv->ver_res; y++)
{
    for(x = area->x1; x <= area->x2; x++)
    {
        FrameBuffer[y*disp_drv->ver_res + x] = (u32)lv_color_to32(*color_p);
        color_p++;

    }

}


lark_lcd_display_update();
lv_disp_flush_ready(disp_drv);

}

is WRONG!!

You should be multiplying by hor_res. Also, FrameBuffer should be declared as a pointer matching your color size. If it’s 32bpp it should be uint32_t (u32). If it’s 16bpp it should be uint16_t (u16).

FrameBuffer is my lcd driver start address.i used 16bpp

volatile u8 *FrameBuffer = (u8 *)0x2003C000;

would you tell me how lvgl pixels display to the screen?

i init buffer by the address of lcd driver update

“Hello,word” mirroring displayd


for(y = area->y1; y <= area->y2 && y <disp_drv->ver_res; y++)
{
for(x = area->x1; x <= area->x2; x++)
{
FrameBuffer[disp_drv->hor_res] = (uint)lv_color_to16(*color_p);
color_p++;

    }

}

There are two kind of buffers:
The ‘working’ buffer for lvgl:
That’s the buffer you set by the call of lv_disp_buf_init (). This buffer hasn’t to be the same size as the full frame buffer, which the LCD needs.

Within the flush function the content of the ‘working’ buffer has to be copied into the LCD’s real frame buffer. Which is of course the full size.

Your flush function DON’T follows the hint from embeddedt.
Your code does almost nothing:

FrameBuffer[disp_drv->hor_res] = (uint)lv_color_to16(*color_p);

try this:

FrameBuffer[(y * disp_drv->hor_res) + x] = lv_color_to16 (*color_p);

And for hal_init try this:

static lv_disp_buf_t disp_buf1;
static lv_color_t    buf1_1[LV_HOR_RES_MAX * 40];

lv_disp_buf_init (&disp_buf1, buf1_1, NULL, LV_HOR_RES_MAX * 40)

thank for your guide.when i try your code.display as below