CPU usage is always 99% and screen flickers if full_refresh equals 0

MCU: NXP MIMXRT1176DVMAA, with a MIPI screen
LVGL version:8.3.2

I’ve implement SDK examples:lvgl_guider_cm7 from NXP which enables vglite,but the cpu usage is 99% even there are only two labels and one button on the screen.

And the screen displays too slowly with about 500ms delay if I switch a focus from button to button.

Then I increase the vTaskDelay(1) to vTaskDelay(100) after lv_task_handler() in the main loop,cpu usage decreases to 30% or less(it’s changing,one second is 30%,one second is 50%,why?),but I don’t think it’s the issue.

I find that lv_task_handler() will execute about 700ms.

The most time consuming code is as below:

_lv_disp_refr_timer
	refr_invalid_areas
		refr_area
			refr_area_part(full_refresh == 1 branch)
refr_area_part
{
    ......
    else {
        /*Refresh the previous screen if any*/
        if(disp_refr->prev_scr) {
            if(top_prev_scr == NULL) top_prev_scr = disp_refr->prev_scr;
            refr_obj_and_children(draw_ctx, top_prev_scr); /* not executed */
        }

        if(top_act_scr == NULL) top_act_scr = disp_refr->act_scr;
        /* take up to 600ms! */
        refr_obj_and_children(draw_ctx, top_act_scr);
    }
    /*Also refresh top and sys layer unconditionally*/
    /* take up to 100ms! */
    refr_obj_and_children(draw_ctx, lv_disp_get_layer_top(disp_refr));
    refr_obj_and_children(draw_ctx, lv_disp_get_layer_sys(disp_refr));
    draw_buf_flush(disp_refr);
}

the function refr_obj_and_children is so time-consuming.What can I do to speed the function?

By the way,the screen will flicker from one incomplete screen to another if I set full_refresh to 0.How can I fix this?

all right,I’ve solved the 99% issue by setting the Optimize Level to -O3.Now cpu usage is 50%.
1.I wonder how it affects the cpu usage?Is it normal that the cpu usage is 99% if I don’t optimize the code?
2.And also,the screen will flicker from one incomplete screen to another if I set full_refresh to 0.How can I fix this?

Seems your config isnt good. Try start with buffers and display driver config.
Next show cb funcs . You write MIPI , this can be hires for example 1280x720 and manage this isnt simple job.

Is that normal the cpu usage is 99% if I don’t optimize code?
The resolution of the screen is 480x640.The flush_cb doesn’t take a lot of time,about 10ms.
I’ve tried to set LV_MEM_SIZE,LV_MEM_BUF_MAX_NUM,LV_LAYER_SIMPLE_BUF_SIZE,LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE to big,but all don’t work.
refr_obj_and_children takes a lot of time,is that relevant to the MIPI config?

disp_drv.flush_cb = DEMO_FlushDisplay;

static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
    DEMO_FLUSH_DCACHE();
    g_dc.ops->setFrameBuffer(&g_dc, 0, (void *)color_p);  //DC_FB_LCDIFV2_SetFrameBuffer
	/* wait for a semaphore gived in DC_FB_LCDIFV2_IRQHandler */
    DEMO_WaitBufferSwitchOff();
    lv_disp_flush_ready(disp_drv);
}

status_t DC_FB_LCDIFV2_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer)
{
    assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
    dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;

    LCDIFV2_SetLayerBufferAddr(dcHandle->lcdifv2, layer, (uint32_t)(uint8_t *)frameBuffer);
    dcHandle->layers[layer].inactiveBuffer = frameBuffer;
	
    if (dcHandle->layers[layer].enabled)
    {
        LCDIFV2_TriggerLayerShadowLoad(dcHandle->lcdifv2, layer);
        dcHandle->layers[layer].shadowLoadPending = true;
        dcHandle->layers[layer].framePending      = true;
    }
    return kStatus_Success;
}

For full_refresh=0,the screen flickers,it seems the issue of the LCD controller,but I’ve no idea.

Im not expert for NXP, but hw based (video mipi mode) displays control require direct mode in lvgl. If your MIPI is in command mode = high speed SPI
Read docu about it.
In direct mode flush_cb require only line lv_disp_flush_ready(disp_drv);

Hi,
Regarding the CPU usage, to keep system responsive, please use a suitable vTaskDelay value. more details, please refer to Timer Handler — LVGL documentation

As I know the MIMXRT1176DVMAA large panel(1280x720) doesn’t support partial refresh. so you can’t change the full_refresh to 0.