最近有個(gè)項(xiàng)目在做基于stm32h7的交互界面制作,大概需要通過lvgl圖形庫做11個(gè)界面加上一堆控件(可以看一下下面的圖,只能說真不少),然后就出現(xiàn)了燒錄程序后,就會(huì)出現(xiàn)白屏(大概率就是卡死了),一開始想簡化一下頁面,注釋了幾個(gè)(治標(biāo)不治本,所以再找了別的方法后面),但又會(huì)出現(xiàn)切換幾次頁面就卡死的情況。。。于是才注意到內(nèi)存泄露問題,查了好幾個(gè)文檔,也沒看太懂,就采用了一個(gè)比較粗暴的方式暫時(shí)先把問題解決了(目前11個(gè)頁面瘋狂切換不會(huì)卡死),之后有時(shí)間再研究一下更專業(yè)的方法,先分享一下這個(gè)比較粗暴的方法哈哈哈。
解決問題1:開機(jī)白屏
解決問題2:切換頁面卡死
一、開機(jī)白屏
這個(gè)主要是內(nèi)存不太夠,直接初始化完內(nèi)存就爆了所以白屏了,這部分解決的辦法我是采用了外部的sdram來存儲(chǔ)(不過正點(diǎn)原子說不推薦哈,但由于內(nèi)存爆了實(shí)在沒辦法哈哈哈)
具體的操作:
可以參考正點(diǎn)原子的視頻:第9講 基礎(chǔ)篇-LVGL移植(外部SRAM)_嗶哩嗶哩_bilibili
1、由于阿波羅板子自帶sdram,所以就省去了移植。直接可以在(我是基于正點(diǎn)原子的例程:實(shí)驗(yàn)31 觸摸屏實(shí)驗(yàn)來搭建的),可以看到在HARDWARE里面有sdram.c,同時(shí)例程main.c寫好了SDRAM_Init();? ?所以基本的環(huán)境都做好了,直接可以操作了
2、進(jìn)入sdram.c,右鍵選擇Toggle Header/Code File跳轉(zhuǎn)到sdram.h文件(也可以直接打開哈)
3、復(fù)制SDRAM開始地址
4、打開lv_conf.h文件,修改LV_MEM_ADR=0為這一串代碼如下圖。?LV_MEM_ADR == (0XC0000000+1280*800*2),其中1280*800*2是因?yàn)長CD所需的緩存數(shù)組大小為1280*800,同時(shí)u16兩個(gè)字節(jié)所以乘2(就是sdram要把這部分大小留給lcd緩存數(shù)組,所以需要對內(nèi)存地址進(jìn)行偏移)5、把內(nèi)存大小修改的更合適,我原本大概是幾十,直接擴(kuò)大到300就完全夠了
6、燒錄,不再白屏了
二、切換頁面卡死
1、打開ui.c仔細(xì)看下面這個(gè)代碼,也就是在按下button29的時(shí)候會(huì)觸發(fā)事件切換頁面,對應(yīng)切換頁面的代碼是:
_ui_screen_change(ui_Screen3, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0);
可以看這個(gè)切換頁面函數(shù)內(nèi)容是什么(在ui_helpers.c文件內(nèi)):
可以看到切換頁面時(shí)候,并沒有清除上個(gè)頁面的東西,所以頁面切換多了占得內(nèi)存就多了。
所以要想辦法在切換頁面時(shí)候,清除上個(gè)頁面的東西。
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就可以自動(dòng)清除了,但我試了一下效果不是很理想,所以采用下述方式。
2、清除對象有關(guān)的函數(shù)介紹
可以參考這個(gè)視頻,介紹的也很清楚
4.3-LVGL基礎(chǔ)知識--創(chuàng)建對象與刪除對象_嗶哩嗶哩_bilibili
最后采用了lv_obj_clean(lv_obj_t*obj)這個(gè)函數(shù)會(huì)比較方便。
3、修改_ui_screen_change函數(shù)
主要就是做一個(gè)清除再顯示的操作。
首先創(chuàng)建對象,然后獲取當(dāng)前活動(dòng)的屏幕的對象,之后刪除該對象(上面的控件會(huì)一起刪掉)
lv_obj_t * act_scr = lv_scr_act();
lv_obj_clean(act_scr);
然后判斷要切到的頁面是什么,由于每次都刪除了上一個(gè)頁面,所以需要重新初始化(記得在ui_helpers.c內(nèi)包含ui.h頭文件哈),然后采用顯示界面的函數(shù)~就OK啦。為什么不用原來?lv_scr_load_anim(target, fademode, spd, delay, false);這個(gè),我也不知道,實(shí)測了發(fā)現(xiàn)用這個(gè)不行。。。后續(xù)再對比一下看看嘿嘿。
if (target == ui_Screen1)
{
ui_Screen1_screen_init();
lv_disp_load_scr(ui_Screen1);
}
?完整代碼:文章來源:http://www.zghlxwxcb.cn/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);
}
}
歡迎大家交流~文章來源地址http://www.zghlxwxcb.cn/news/detail-839592.html
到了這里,關(guān)于采用一種比較粗暴的方法解決lvgl切換screen時(shí)候造成的卡死問題/LVGL/stm32/內(nèi)存的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!