最近有个项目在做基于stm32h7的交互界面制作,大概需要通过lvgl图形库做11个界面加上一堆控件(可以看一下下面的图,只能说真不少),然后就出现了烧录程序后,就会出现白屏(大概率就是卡死了),一开始想简化一下页面,注释了几个(治标不治本,所以再找了别的方法后面),但又会出现切换几次页面就卡死的情况。。。于是才注意到内存泄露问题,查了好几个文档,也没看太懂,就采用了一个比较粗暴的方式暂时先把问题解决了(目前11个页面疯狂切换不会卡死),之后有时间再研究一下更专业的方法,先分享一下这个比较粗暴的方法哈哈哈。
解决问题1:开机白屏
解决问题2:切换页面卡死
一、开机白屏
这个主要是内存不太够,直接初始化完内存就爆了所以白屏了,这部分解决的办法我是采用了外部的sdram来存储(不过正点原子说不推荐哈,但由于内存爆了实在没办法哈哈哈)
具体的操作:
可以参考正点原子的视频:第9讲 基础篇-LVGL移植(外部SRAM)_哔哩哔哩_bilibili
1、由于阿波罗板子自带sdram,所以就省去了移植。直接可以在(我是基于正点原子的例程:实验31 触摸屏实验来搭建的),可以看到在HARDWARE里面有sdram.c,同时例程main.c写好了SDRAM_Init(); 所以基本的环境都做好了,直接可以操作了
2、进入sdram.c,右键选择Toggle Header/Code File跳转到sdram.h文件(也可以直接打开哈)
3、复制SDRAM开始地址
4、打开lv_conf.h文件,修改LV_MEM_ADR=0为这一串代码如下图。 LV_MEM_ADR == (0XC0000000+1280*800*2),其中1280*800*2是因为LCD所需的缓存数组大小为1280*800,同时u16两个字节所以乘2(就是sdram要把这部分大小留给lcd缓存数组,所以需要对内存地址进行偏移)5、把内存大小修改的更合适,我原本大概是几十,直接扩大到300就完全够了
6、烧录,不再白屏了
二、切换页面卡死
1、打开ui.c仔细看下面这个代码,也就是在按下button29的时候会触发事件切换页面,对应切换页面的代码是:
_ui_screen_change(ui_Screen3, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0);
可以看这个切换页面函数内容是什么(在ui_helpers.c文件内):
可以看到切换页面时候,并没有清除上个页面的东西,所以页面切换多了占得内存就多了。
所以要想办法在切换页面时候,清除上个页面的东西。
void _ui_screen_change(lv_obj_t * target, lv_scr_load_anim_t fademode, int spd, int delay)
{ lv_scr_load_anim(target, fademode, spd, delay, false);
}
一开始我看有文档说把false改成true就可以自动清除了,但我试了一下效果不是很理想,所以采用下述方式。
2、清除对象有关的函数介绍
可以参考这个视频,介绍的也很清楚
4.3-LVGL基础知识--创建对象与删除对象_哔哩哔哩_bilibili
最后采用了lv_obj_clean(lv_obj_t*obj)这个函数会比较方便。
3、修改_ui_screen_change函数
主要就是做一个清除再显示的操作。
首先创建对象,然后获取当前活动的屏幕的对象,之后删除该对象(上面的控件会一起删掉)
lv_obj_t * act_scr = lv_scr_act();
lv_obj_clean(act_scr);
然后判断要切到的页面是什么,由于每次都删除了上一个页面,所以需要重新初始化(记得在ui_helpers.c内包含ui.h头文件哈),然后采用显示界面的函数~就OK啦。为什么不用原来 lv_scr_load_anim(target, fademode, spd, delay, false);这个,我也不知道,实测了发现用这个不行。。。后续再对比一下看看嘿嘿。
if (target == ui_Screen1)
{
ui_Screen1_screen_init();
lv_disp_load_scr(ui_Screen1);
}
完整代码:文章来源:https://www.toymoban.com/news/detail-839592.html
void _ui_screen_change(lv_obj_t * target, lv_scr_load_anim_t fademode, int spd, int delay)
{
lv_obj_t * act_scr = lv_scr_act();
lv_obj_clean(act_scr);
if (target == ui_Screen1)
{
ui_Screen1_screen_init();
lv_disp_load_scr(ui_Screen1);
}
if (target == ui_Screen2)
{
ui_Screen2_screen_init();
lv_disp_load_scr(ui_Screen2);
}
if (target == ui_Screen3)
{
ui_Screen3_screen_init();
lv_disp_load_scr(ui_Screen3);
}
if (target == ui_Screen4)
{
ui_Screen4_screen_init();
lv_disp_load_scr(ui_Screen4);
}
if (target == ui_Screen5)
{
ui_Screen5_screen_init();
lv_disp_load_scr(ui_Screen5);
}
if (target == ui_Screen6)
{
ui_Screen6_screen_init();
lv_disp_load_scr(ui_Screen6);
}
if (target == ui_Screen7)
{
ui_Screen7_screen_init();
lv_disp_load_scr(ui_Screen7);
}
}
欢迎大家交流~文章来源地址https://www.toymoban.com/news/detail-839592.html
到了这里,关于采用一种比较粗暴的方法解决lvgl切换screen时候造成的卡死问题/LVGL/stm32/内存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!