硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1632|回复: 4
收起左侧

[emWin] LVGL切换页面出现内存溢出问题

[复制链接]

2

主题

33

回帖

39

积分

新手上路

积分
39
发表于 2024-9-30 17:01:03 | 显示全部楼层 |阅读模式
现在项目开发阶段遇到一个LVGL内存溢出的问题。项目没有触屏,用实体按键进行控制,有四个实体按键,分别是确认,上,下,返回,带freertos。
控件只使用了容器,label,btn三种。


芯片:STM32F405RGT6
问题:在进行页面切换的时候,能通过lvgl的监控看到占用内存在一点一点往上加。
做了一些尝试,最后排查问题:
1、分别对页面上的控件进行隔离,再进行页面自动切换(不使用实体按键),排除了容器和label控件的怀疑;

2、创建两个页面分别只保留一个按键,再进行页面自动切换(不使用实体按键),内存不会增加,是正常的;
3、将两个页面上的按键进行keypad,group捆绑,再设置相应的回调函数,使用实体按键进行页面切换,内存会以0.1k每次进行增加;
4、将两个页面上的按键进行keypad,group捆绑,再设置相应的回调函数,进行页面自动切换(不使用实体按键),内存会以0.1k每次进行增加;

以上是遇到的情况。
我的代码部分:
1、输入接口部分,直接读取io口进行获取键值:

2、GUI页面部分,是使用guiguider自动生成后,根据项目做过修改,非常简单,直接创建页面和按钮。
界面1:
[C] 纯文本查看 复制代码
void ui_about_page_init(void)
{

    // Write codes screen_info
    ui_about_page = lv_obj_create(NULL);
    lv_obj_set_size(ui_about_page, 240, 300);
    lv_obj_set_scrollbar_mode(ui_about_page, LV_SCROLLBAR_MODE_OFF);

    // Write style for screen_info, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
    lv_obj_set_style_bg_opa(ui_about_page, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(ui_about_page, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_grad_dir(ui_about_page, LV_GRAD_DIR_NONE, LV_PART_MAIN | LV_STATE_DEFAULT);
    ui_about_return_btn = lv_btn_create(ui_about_page);
    ui_about_return_label = lv_label_create(ui_about_return_btn);
    
    lv_label_set_text(ui_about_return_label, "返回");
    lv_label_set_long_mode(ui_about_return_label, LV_LABEL_LONG_WRAP);
    lv_obj_align(ui_about_return_label, LV_ALIGN_RIGHT_MID, 0, 0);
    lv_obj_set_style_pad_all(ui_about_return_btn, 0, LV_STATE_DEFAULT);
    lv_obj_set_width(ui_about_return_label, LV_PCT(100));
    lv_obj_set_pos(ui_about_return_btn, 170, 290);
    lv_obj_set_size(ui_about_return_btn, 70, 30);

    // Write style for screen_info_btn_2, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
    lv_obj_set_style_bg_opa(ui_about_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(ui_about_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_radius(ui_about_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_shadow_width(ui_about_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(ui_about_return_btn, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_font(ui_about_return_btn, &lv_font_OPPOSans_Regular_20, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_opa(ui_about_return_btn, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_align(ui_about_return_btn, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN | LV_STATE_DEFAULT);
    ui_about_key_set();
}

static void ui_event_about_keys_cb(lv_event_t *e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    uint32_t *key_id = lv_event_get_param(e);

    if (event_code == LV_EVENT_KEY)
    {
        switch (*key_id)
        {
        case LV_KEY_ESC:
            ui_menu_page_init();
            lv_scr_load_anim(ui_menu_page, LV_SCR_LOAD_ANIM_NONE, 100, 0, true);
            break;

        default:
            break;
        }
    }
}

static void ui_about_key_set(void)
{
    extern lv_indev_t *indev_keypad;

    lv_group_t *group = lv_group_create();
    lv_indev_set_group(indev_keypad, group);

    lv_obj_add_event_cb(ui_about_return_btn, ui_event_about_keys_cb, LV_EVENT_ALL, NULL);
    lv_group_add_obj(group, ui_about_return_btn);
}



界面2:
[C] 纯文本查看 复制代码
void ui_menu_page_init(void)
{
    // Write codes ui_menu_page
    ui_menu_page = lv_obj_create(NULL);
    lv_obj_set_size(ui_menu_page, 240, 300);
    lv_obj_set_scrollbar_mode(ui_menu_page, LV_SCROLLBAR_MODE_OFF);

    // Write style for screen_setting, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
    lv_obj_set_style_bg_opa(ui_menu_page, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(ui_menu_page, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_grad_dir(ui_menu_page, LV_GRAD_DIR_NONE, LV_PART_MAIN | LV_STATE_DEFAULT);
    // Write codes ui_menu_return_btn
    ui_menu_return_btn = lv_btn_create(ui_menu_page);
    ui_menu_return_btn_label = lv_label_create(ui_menu_return_btn);
    lv_obj_remove_style(ui_menu_return_btn, NULL, LV_STATE_FOCUSED);

    lv_label_set_text(ui_menu_return_btn_label, "返回");
    lv_label_set_long_mode(ui_menu_return_btn_label, LV_LABEL_LONG_WRAP);
    lv_obj_align(ui_menu_return_btn_label, LV_ALIGN_RIGHT_MID, 0, 0);
    lv_obj_set_style_pad_all(ui_menu_return_btn, 0, LV_STATE_DEFAULT);
    lv_obj_set_width(ui_menu_return_btn_label, LV_PCT(100));
    lv_obj_set_pos(ui_menu_return_btn, 170, 50);
    lv_obj_set_size(ui_menu_return_btn, 70, 30);

    // Write style for ui_menu_return_btn, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
    lv_obj_set_style_bg_opa(ui_menu_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);

    lv_obj_set_style_bg_opa(ui_menu_return_btn, 255, LV_PART_MAIN | LV_STATE_FOCUSED);
    lv_obj_set_style_bg_color(ui_menu_return_btn, lv_color_hex(0x2195f6), LV_PART_MAIN | LV_STATE_FOCUSED);

    lv_obj_set_style_border_width(ui_menu_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_radius(ui_menu_return_btn, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_shadow_width(ui_menu_return_btn, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(ui_menu_return_btn, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_font(ui_menu_return_btn, &lv_font_OPPOSans_Regular_20, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_opa(ui_menu_return_btn, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_text_align(ui_menu_return_btn, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN | LV_STATE_DEFAULT);
    ui_menu_key_set();
}

static void ui_event_menu_list_cb(lv_event_t *e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    uint32_t *key_id = lv_event_get_param(e);

    if (event_code == LV_EVENT_KEY)
    {
        lv_obj_t *act_scr = lv_scr_act();
        switch (*key_id)
        {
        case LV_KEY_ENTER:
            break;

        case LV_KEY_ESC:
            ui_about_page_init();
            lv_scr_load_anim(ui_about_page, LV_SCR_LOAD_ANIM_NONE, 100, 0, true);

            break;
        case LV_KEY_PREV:
            printf("press up\r\n");

            break;

        case LV_KEY_NEXT:
            printf("press down\r\n");

            break;

        default:
            break;
        }
    }
}

static void ui_menu_key_set(void)
{
    extern lv_indev_t *indev_keypad;

    lv_group_t *group = lv_group_create();
    lv_indev_set_group(indev_keypad, group);
    lv_obj_add_event_cb(ui_menu_return_btn, ui_event_menu_list_cb, LV_EVENT_ALL, NULL);
    lv_group_add_obj(group, ui_menu_return_btn);

}



这个是两个界面的代码,通过按键进行页面切屏。
我发现在没捆绑按键回调事件的时候,自动切换页面时,内存是正常的,一捆绑按键事件,按键会有一个聚焦的显示,再进行页面切换就会有内存碎片产生。
这个问题排查了好几天,依旧没有思路,请大伙帮忙看看咋回事。多谢!!!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2024-10-1 01:00:59 | 显示全部楼层
帮顶下,这个还真不太清楚。

这种类似的案例好像不少开源的,楼主有参考对比过没。
回复

使用道具 举报

2

主题

33

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-10-1 08:51:21 来自手机 | 显示全部楼层
eric2013 发表于 2024-10-1 01:00
帮顶下,这个还真不太清楚。

这种类似的案例好像不少开源的,楼主有参考对比过没。

硬汉哥,lvgl开源项目大部分是触屏的,创建按钮是不需要focus的,这个我在nxp的guiguider上面试过了,内存是属于正常的。我也找过实体按键的,没有找到通过实体按键控制的开源项目。还有一个问题求助,就是如果只需要通过实体按键控制菜单这种,是使用lvgl,emwin开发快一点省心一点,项目的界面比较少,现在换框架还来得及。
回复

使用道具 举报

0

主题

290

回帖

290

积分

高级会员

积分
290
发表于 2024-10-1 17:09:20 | 显示全部楼层
浅末哈哈 发表于 2024-10-1 08:51
硬汉哥,lvgl开源项目大部分是触屏的,创建按钮是不需要focus的,这个我在nxp的guiguider上面试过了,内 ...

窗口的LV_EVENT_SCREEN_UNLOADED回调函数使用,看看是不是group没释放。
回复

使用道具 举报

2

主题

33

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-10-8 09:02:42 | 显示全部楼层
regbbs 发表于 2024-10-1 17:09
窗口的LV_EVENT_SCREEN_UNLOADED回调函数使用,看看是不是group没释放。

多谢大哥提供的思路!我在切换页面前调用了lv_group_del(),内存就正常了!之前应该是切换页面后group没有释放,导致多次创建产生内存碎片。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 23:48 , Processed in 0.051545 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表