STM32H7 LTDC + DMA2D + SDRAM High CPU usage

Description

High CPU usage while updating basic arcs and sliders.

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

Custom stm32h743, compiler GCC and makefile

What LVGL version are you using?

Current master

What do you want to achieve?

Improve FPS and cpu usage.

What have you tried so far?

Checking if DMA2D is working, working out the best SDRAM timing and CLK.
If i adjust the sleep in the GFX thread to a lower value it causes the fps to go down significantely and cpu usage to spike up to 95-99% (20-24fps). Also I’ve noticed that using buffers below 50% of the screen size impacts the performance while those above 50% dont affect it at all.

As for the driver im using the LTDC lvgl driver with some adjustment done by me for usage with ChibiOS.

Code to reproduce

#include "ch.h"
#include "hal.h"
#include "lvgl_thread.h"
#include <string.h>
#include "lvgl/lvgl.h"
#include "ui/ui.h"
#include "chprintf.h"
#include "nxrd.h"

uint8_t frame_buffer1[600 * 1024 * 2] __attribute__((section(".sdram"), aligned(1)));
uint8_t frame_buffer_optional[600 * 1024 * 2] __attribute__((section(".sdram"), aligned(1)));


static THD_WORKING_AREA(waLV_TIMER_HANDLER, 4096);
static THD_FUNCTION(LV_TIMER_HANDLER, arg)
{
    (void)arg;
    chRegSetThreadName("LV_TIMER_HANDLER");
    uint32_t sleep = 0;
    while (true)
    {
        sleep = lv_timer_handler();
        if (sleep == LV_NO_TIMER_READY)
            sleep = LV_DEF_REFR_PERIOD;
        if (sleep <= 0)
            sleep = 1;
        chThdSleepMilliseconds(sleep);
    }
}

static THD_WORKING_AREA(waLV_GFX, 4096);
static THD_FUNCTION(LV_GFX, arg)
{
    (void)arg;
    chRegSetThreadName("LV_GFX_HANDLER");
    lv_lock();
    lv_obj_t *screen = lv_obj_create(lv_scr_act());
    lv_obj_set_size(screen, 1024, 600);
    lv_obj_set_style_bg_color(screen, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(screen, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_radius(screen, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_t *splash = lv_image_create(screen);
    lv_image_set_src(splash, getimage());
    lv_obj_align(splash, LV_ALIGN_CENTER, 0, 0);
    lv_unlock();
    chThdSleepMilliseconds(3000);
    lv_lock();
    lv_obj_del(splash);
    lv_obj_del(screen);
    ui_init();
    lv_unlock();
    float test = 0;
    bool n = false;
    while (true)
    {
        lv_lock();
        for (int i = 0; i < 8; i++)
        {
            update_values(test, 0, i);
        }
        if(!n)
        {
            test += 0.5f;
        }
        else if (n)
        {
            test -= 0.5f;
        }
        if (test >= 100)
        {
            n = true;
        }
        else if (test <= 0)
        {
            n = false;
        }
        lv_unlock();
        chThdSleepMilliseconds(100);
    }
}

static void gpt_lvgl_tick(GPTDriver *gptp) {
    (void)gptp;
    lv_tick_inc(1);
}

static const GPTConfig gptcfg = {
    .frequency = 100000,
    .callback  = gpt_lvgl_tick,
    .cr2       = 0,
    .dier      = 0
};

void startLVGL()
{
    palSetPad(GPIOH, 6U);
    lv_init();
    lv_display_t *disp = lv_st_ltdc_create_partial(frame_buffer1, frame_buffer_optional, sizeof(frame_buffer_optional), 0);
    chThdCreateStatic(waLV_TIMER_HANDLER, sizeof(waLV_TIMER_HANDLER), NORMALPRIO + 8, LV_TIMER_HANDLER, NULL);
    gptStart(&GPTD1, &gptcfg);
    gptStartContinuous(&GPTD1, 100);
    chThdCreateStatic(waLV_GFX, sizeof(waLV_GFX), NORMALPRIO, LV_GFX, NULL);
}

Screenshot and/or video