解决LVGL切换Screen卡死问题的粗暴方法/LVGL/STM32/内存优化

最近有个项目在做基于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);
	}

 完整代码:

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);
	}
	

}

欢迎大家交流~

作者:Guo_ivy

物联沃分享整理
物联沃-IOTWORD物联网 » 解决LVGL切换Screen卡死问题的粗暴方法/LVGL/STM32/内存优化

发表评论