Hard fault migrating LVGL

Hard fault migrating LVGL from 8.0 to 9.1 on a STM32H723ZGTx


I’m trying to migrate my LVGL 8.0 project currently running on a STM32H723ZGTx to the version 9.1. My project comprehend a display attached to the MCU, and the MCU itself has attached an external SRAM.
I’ve followed the new STM32 guide and also checked the Changelog.

I use the two display buffers for my screen, and this is my flush cb function.

void stm32_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {

    lv_disp_t *disp = _lv_refr_get_disp_refreshing();
    lv_color_t *dma_xfer_src, *dma_xfer_dst;


    dma_xfer_src = color_p;
    if (color_p == framebuffer_1) {
        dma_xfer_dst = framebuffer_2;
    } else {
        dma_xfer_dst = framebuffer_1;

    for (size_t i = 0; i < disp->inv_p; i++) {
        dma2d_copy_area(disp->inv_areas[i], (uint32_t)dma_xfer_src, (uint32_t)dma_xfer_dst);

Because in the 9.1 version there is no more invalidate areas field inside a `lv_disp_t (correct me if I’m wrong), I’ve changed the flush function by removing

 for (size_t i = 0; i < disp->inv_p; i++) {
        dma2d_copy_area(disp->inv_areas[i], (uint32_t)dma_xfer_src, (uint32_t)dma_xfer_dst);

This part isn’t necessary but it was an optimization, also mentioned in the faq

So, in my main.c after all the initialization functions added by STM32CubeMX, I’ve called lv_init() and my screen driver init function, that, before the changes for the 9.1 version, was

void screen_driver_init() {
    static lv_disp_draw_buf_t draw_buf; //internal graphic buffer(s) called draw buffer(s)
    lv_disp_draw_buf_init(&draw_buf, framebuffer_1, framebuffer_2, FRAMEBUFFER_SIZE);
    lv_display_driver.direct_mode = true;
    lv_display_driver.hor_res     = SCREEN_WIDTH;
    lv_display_driver.ver_res     = SCREEN_HEIGHT;
    lv_display_driver.flush_cb    = stm32_flush_cb;
    lv_display_driver.draw_buf    = &draw_buf;
    lv_display_driver.dpi         = 1;


and now I changed to

    lv_display_t * disp = lv_display_create(LCD_SCREEN_WIDTH, LCD_SCREEN_HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/
    lv_display_set_flush_cb(disp, stm32_flush_cb); /*Set a flush callback to draw to the display*/
    lv_display_set_buffers(disp, framebuffer_1, framebuffer_2, FRAMEBUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/

After that I’ve while(1) with refresh graphics function into it, with


Unfortunately, even if I’ve checked all the info about it, with this porting to lvgl version 9.1 the MCU goes in hard fault doing lv_timer_handler(). This is the stack trace

<signal handler called>@0xffffffe9 (Unknown Source:0)
lv_draw_rect@0x0800e4e4 (../lvgl-stm32/lvgl/src/draw/lv_draw_rect.c:182)
lv_obj_draw@0x0800643e (../lvgl-stm32/lvgl/src/core/lv_obj.c:479)
lv_obj_event_base@0x08007572 (../lvgl-stm32/lvgl/src/core/lv_obj_event.c:86)
event_send_core@0x080075b8 (../lvgl-stm32/lvgl/src/core/lv_obj_event.c:359)
lv_obj_send_event@0x0800763c (../lvgl-stm32/lvgl/src/core/lv_obj_event.c:64)
lv_obj_redraw@0x0800b272 (../lvgl-stm32/lvgl/src/core/lv_refr.c:110)
refr_obj_and_children@0x0800b7e2 (../lvgl-stm32/lvgl/src/core/lv_refr.c:790)
refr_area_part@0x0800b916 (../lvgl-stm32/lvgl/src/core/lv_refr.c:723)
refr_area@0x0800c03c (../lvgl-stm32/lvgl/src/core/lv_refr.c:650)
refr_invalid_areas@0x0800c03c (../lvgl-stm32/lvgl/src/core/lv_refr.c:566)
_lv_display_refr_timer@0x0800c03c (../lvgl-stm32/lvgl/src/core/lv_refr.c:374)
lv_timer_exec@0x0801969c (../lvgl-stm32/lvgl/src/misc/lv_timer.c:300)
lv_timer_handler@0x0801969c (../lvgl-stm32/lvgl/src/misc/lv_timer.c:105)
lv_timer_handler@0x0801969c (../lvgl-stm32/lvgl/src/misc/lv_timer.c:63)
refresh_graphics@0x080286c2 (../Core/UI/steering/graphics_manager.c:28)
main@0x0802592e (../Core/Src/main.c:198)

What could cause this hard fault? Before migrating to 9.1 version, all software and the display itself worked.

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

I’m using a STM32H723ZGTx and gcc to compile, using the STM32 for VSCode extension

What LVGL version are you using?


What do you want to achieve?

Make the display working

Code to reproduce


Screenshot and/or video

This is what the display is showinfg during the hard fault

check how I implemented lvgl on F429-disco.
I used DMA2D with LTDC to get the picture.
Check the LCD controller source file:

Are you using LVGL version 9+ in this project? Because at line 73 I see the calling of the function lv_disp_drv_init that is part of LVGL version 8, but not in 9 anymore.

The version 8 already works in my project, but the main thing is that I want to migrate to version 9

Even with V9, you still need to call this function to inform LvGL that the buffer has been moved to the LCD.