lvgl的内存分配和释放提供了两套方案,可以通过lv_conf.h头文件中的宏LV_MEM_CUSTOM来控制使用哪个方案,该宏定义值为0,则表示使用lvgl内置的内存分配函数lv_mem_alloc()和lv_mem_free();该宏定义值为1,则表示使用自定义“malloc()/free()/realloc()”,根据代码中的逻辑,其实就是使用系统标准的动态内存分配函数malloc()/free()/realloc(),这些标准函数此处不细说,这里要重点说一下lvgl的内置内存管理的函数。

        lvgl默认配置就是使用其内置的内存管理函数,根据头文件中定义及相关注释,使用内置的内存管理函数,需要用到内存块大小定义的宏LV_MEM_SIZE,按照注释说明,此值必须大于2kb,此宏的值默认为32U * 1024U,即32kb。此内存大小为lvgl内置内存管理模块初始化的内存池的大小,对后续的界面显示有一定的影响。lvgl内置的内存管理是基于TLSF算法的内存管理,对TLSF算法有兴趣的小伙伴可以自行百度或者查看下面的链接了解关于TLSF算法。LiteOS内存管理:TLSF算法 - 简书 (jianshu.com)内存管理的机制不是本文重点要讲的内容,本文重点要将的是内存池大小与界面显示的关系。https://www.jianshu.com/p/01743e834432       

        在本人开发某个项目UI的过程中发现,创建一个app后,里面显示的控件有数量限制,但对每种控件数量限制还不一样,如按钮可以创建的个数和图标控件可以创建的个数不同。具体现象可以通过如下代码来测试(lvgl框架自行搭建,此处仅为测试部分的代码):

static void lv_example_flex_1(void)
{
    static lv_coord_t col_dsc[] = {100, 100, 100, 100, LV_GRID_TEMPLATE_LAST};
    static lv_coord_t row_dsc[] = {30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,
                                   30,30,30,30,30,30,30,30,30,30,LV_GRID_TEMPLATE_LAST};
    lv_obj_t * cont = lv_obj_create(lv_scr_act());
    lv_obj_set_align(cont,LV_ALIGN_CENTER);
    lv_obj_set_style_opa(cont, cont_opa,0);
    lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_layout(cont,LV_LAYOUT_GRID);
    lv_obj_set_grid_dsc_array(cont, col_dsc, row_dsc);

    static lv_style_t text_style;
    lv_style_init(&text_style);
    lv_style_set_align(&text_style, LV_ALIGN_CENTER);

    lv_coord_t uiIndex = 0;
    lv_coord_t uiCntCol = sizeof(col_dsc)/sizeof(lv_coord_t)-1;
    for(uiIndex=0; uiIndex<sizeof(row_dsc)/sizeof(lv_coord_t)-1; uiIndex++)
    {
        lv_obj_t * btn = lv_btn_create(cont);
        lv_obj_t * label = lv_label_create(btn);
        lv_label_set_text_fmt(label, "Label %d", uiIndex+1);
        lv_obj_add_style(label, &text_style,0);
        lv_obj_set_grid_cell(btn, LV_GRID_ALIGN_STRETCH, uiIndex%uiCntCol, 1, LV_GRID_ALIGN_STRETCH, uiIndex/uiCntCol, 1);
    }
}

        其中的row_dsc自行进行增减以测试最多能正常显示的控件个数,不能显示的时候会在app界面上全黑显示,什么都没有,如果再增加row_dsc中的元素数量,则可能出现直接编译时报段错误的情况。针对此问题很少有人问道,官方文档也没有针对性的说明,本以为只是代码某处存在数量的限制,但更换显示的控件(如换成只是标签),则可显示的数量还不一样。最后找了各种资料,最后在官方的论坛上找到了某个小伙伴提出的类似的问题,连蒙带猜的找到了lv_conf.h中的内存管理相关的宏定义。

Limitation of the total object - #9 by embeddedt - How-to - LVGL ForumHi, Sir, Is there any limitation of the total object? As I found the lvg lib stop when I create a long list with 100 list_btn . How to improve it ? Best Regards,

https://forum.lvgl.io/t/limitation-of-the-total-object/438/9       

根据论坛的问题,最终找到两种解决方式:

        1、修改LV_MEM_SIZE宏的大小

        根据论坛里面的部分小伙伴的反馈,平均每个控件所占内存控件大致为100-150b左右,经验证修改LV_MEM_SIZE的大小直接影响可以显示的控件数量,本人项目中控件数量比较多,原本20+就已经不能正常显示了,将原来的LV_MEM_SIZE增加一倍后,即可正常显示所有的控件。

        2、直接修改LV_MEM_CUSTOM的值为1,即使用系统的内存管理函数

        此方式不再受LV_MEN_SIZE大小的限制,但也弃用了lvgl内置的基于TLSF算法的内存管理策略,该算法的优缺点请自行百度了解。

        最终本人选择保留lvgl内置的内存管理策略,使用第一种方式进行优化,以保证UI的正常功能,虽然这样使得内存池大小有所增加,但基本单位为kb,对于如今的设备来说基本没有任何影响,就算对于嵌入式设备而言影响也不大。所以有同样问题的小伙伴,此解决方案值得考虑。