Skip to main content
Associate
August 29, 2023
Question

Hardfault memory manager when integrate LVGL into FreeRTOS (FreeRTOS Kernel V10.3.1)

hi all,

Why does the system crash when registering an initialized display driver using lv_disp_drv_register() within “In Register” section? how to replace lv_hal_disp.c for freertos.

1
lv_memset_00(disp, sizeof(lv_disp_t))
After executing the lv_memset_00(disp, sizeof(lv_disp_t)) statement, set the free BlockSize in the BlockLink_t structure to 0 (zero).

then Insert the new block into the list of free blocks (prvInsertBlockIntoFreeList( ( pxNewBlockLink ) )) Due to sufficient space (as subtracting any number from 0 results in a negative number, i.e., a large number), it enters an infinite loop.

2.Create a refresh timer
lv_timer_create(_lv_disp_refr_timer, LV_DISP_DEF_REFR_PERIOD, disp);
why it Add a new head to a linked list to create timer task ?

FreeRTOS Kernel V10.3.1, use heap_4.c
LVGL V8.0.0
board stm32h743

add pvPortRealloc() at heap_4.c

```c

 

void *pvPortRealloc(void *mem, size_t newsize)
{
 if (newsize == 0) {
 vPortFree(mem);
 return NULL;
 }

 void *p;
 p = pvPortMalloc(newsize);
 if (p) {
 /* zero the memory */
 if (mem != NULL) {
 memcpy(p, mem, newsize);
 vPortFree(mem);
 }
 }
 return p;
}

```

 

This topic has been closed for replies.

2 replies

Slh
Senior
August 29, 2023

You should probably increase the TOTAL_HEAP_SIZE in memory management in your RTOS setting and also the Stack size for your task.

Associate
August 29, 2023

hi Slh,

thank your reply.

i have been adjust increase the "heap size", but when 

lv_memset_00(disp, sizeof(lv_disp_t)) // clear lvgl handle struct
After executing the lv_memset_00(disp, sizeof(lv_disp_t)) statement, set the free BlockSize in the BlockLink_t structure to 0 (zero). So ,it not found node to insert or clear free BlockLink size.

```c

lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)

{

lv_disp_t * disp = _lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));

LV_ASSERT_MALLOC(disp);

if(!disp) {

return NULL;

}

 

/*Create a draw context if not created yet*/

if(driver->draw_ctx == NULL) {

lv_draw_ctx_t * draw_ctx = lv_mem_alloc(driver->draw_ctx_size);

LV_ASSERT_MALLOC(draw_ctx);

if(draw_ctx == NULL) return NULL;

driver->draw_ctx_init(driver, draw_ctx);

driver->draw_ctx = draw_ctx;

}

// reset BlockLink_t

lv_memset_00(disp, sizeof(lv_disp_t));

 

disp->driver = driver;

 

disp->inv_en_cnt = 1;

 

lv_disp_t * disp_def_tmp = disp_def;

disp_def = disp; /*Temporarily change the default screen to create the default screens on the

new display*/

/*Create a refresh timer*/

 

// assign invaild value at BlockLink_t struct

disp->refr_timer = lv_timer_create(_lv_disp_refr_timer, LV_DISP_DEF_REFR_PERIOD, disp);

LV_ASSERT_MALLOC(disp->refr_timer);

if(disp->refr_timer == NULL) {

lv_mem_free(disp);

return NULL;

}

 

if(driver->full_refresh && driver->draw_buf->size < (uint32_t)driver->hor_res * driver->ver_res) {

driver->full_refresh = 0;

LV_LOG_WARN("full_refresh requires at least screen sized draw buffer(s)");

}

 

disp->bg_color = lv_color_white();

#if LV_COLOR_SCREEN_TRANSP

disp->bg_opa = LV_OPA_TRANSP;

#else

disp->bg_opa = LV_OPA_COVER;

#endif

 

#if LV_USE_THEME_DEFAULT

if(lv_theme_default_is_inited() == false) {

disp->theme = lv_theme_default_init(disp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED),

LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);

}

else {

disp->theme = lv_theme_default_get();

}

#endif

 

disp->act_scr = lv_obj_create(NULL); /*Create a default screen on the display*/

disp->top_layer = lv_obj_create(NULL); /*Create top layer on the display*/

disp->sys_layer = lv_obj_create(NULL); /*Create sys layer on the display*/

lv_obj_remove_style_all(disp->top_layer);

lv_obj_remove_style_all(disp->sys_layer);

lv_obj_clear_flag(disp->top_layer, LV_OBJ_FLAG_CLICKABLE);

lv_obj_clear_flag(disp->sys_layer, LV_OBJ_FLAG_CLICKABLE);

 

lv_obj_set_scrollbar_mode(disp->top_layer, LV_SCROLLBAR_MODE_OFF);

lv_obj_set_scrollbar_mode(disp->sys_layer, LV_SCROLLBAR_MODE_OFF);

 

lv_obj_invalidate(disp->act_scr);

 

disp_def = disp_def_tmp; /*Revert the default display*/

if(disp_def == NULL) disp_def = disp; /*Initialize the default display*/

 

lv_timer_ready(disp->refr_timer); /*Be sure the screen will be refreshed immediately on start up*/

 

return disp;

}

```

```c

lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data)

{

lv_timer_t * new_timer = NULL;

 

new_timer = _lv_ll_ins_head(&LV_GC_ROOT(_lv_timer_ll));

LV_ASSERT_MALLOC(new_timer);

if(new_timer == NULL) return NULL;

 

new_timer->period = period;

new_timer->timer_cb = timer_xcb;

new_timer->repeat_count = -1;

new_timer->paused = 0;

new_timer->last_run = lv_tick_get();

new_timer->user_data = user_data;

 

timer_created = true;

 

return new_timer;

}

 

 

LV_ATTRIBUTE_FAST_MEM void lv_memset_00(void * dst, size_t len)

{

uint8_t * d8 = (uint8_t *)dst;

uintptr_t d_align = (lv_uintptr_t) d8 & ALIGN_MASK;

 

/*Make the address aligned*/

if(d_align) {

d_align = ALIGN_MASK + 1 - d_align;

while(d_align && len) {

SET8(0);

len--;

d_align--;

}

}

 

uint32_t * d32 = (uint32_t *)d8;

while(len > 32) {

REPEAT8(SET32(0));

len -= 32;

}

 

while(len > 4) {

SET32(0);

len -= 4;

}

 

d8 = (uint8_t *)d32;

while(len) {

SET8(0);

len--;

}

}

```