OpenHarmony輕量化系統的LVGL使用(二)
前言
在做OpenHarmony的LVGL之前,學習了STM32的LVGL移植,其中遇到了很多問題,也學會了很多知識,為下一步的移植打下了基礎。本篇文章主要講解如何移植LVGL到OpenHarmony輕量化系統上。
環境
- OpenHarmony-3.1
- 潤和hispark_pegasus Hi3861開發板
- DevEco Device Tool
- 串口調試助手
- SSD1306 0.96寸OLED屏幕
移植
我當前下載的版本是LVGL8.3版本,大家可以在GitHub上下載獲取源碼:
LVGL8.3_GitHub也可以通過我上傳的源碼附件進行下載。
移植LVGL文件的大致流程:
移植文件
先在applications/sample/wifi-iot/app路徑下新建一個lvgl文件夾,將下圖四個文件加入到lvgl文件夾中,并且lvgl根路徑下的lv_conf_template.h更改名字為lv_conf.h。
取消注釋
在lvgl/examples/porting文件夾中把所需要的文件里的開頭的#if 0改成 #if 1。本次只使用到屏幕驅動,所以只需要將lv_port_disp_template.c和lv_port_disp_template.h改掉即可。
- lv_port_disp_template為屏幕驅動。
- lv_port_fs_template為文件系統驅動。
- lv_port_indev_template為輸入驅動lvgl根路徑下的lv_conf.h將里面開頭的#if 0也要改成#if 1在lvgl/examples/porting文件夾中,將lv_port_disp_template.h中的include修改成如圖所示:
加入編譯
這一步將LVGL加入到編譯里面,需要把以下源文件都添加到lvgl/BUILD.gn里面
- lvgl/examples/porting目錄下的文件。
- lvgl/src目錄下的core draw font hal misc widgets文件夾下的頭文件。
- lvgl/src/extra/目錄下的文件。
- lvgl/src/extra/layouts目錄下所有子目錄文件。
- lvgl/src/extra/themes目錄下所有子目錄文件。
- lvgl/src/extra/widgets目錄下所有子目錄文件。
還需要將lvgl ,src,porting頭文件文件夾目錄添加到include_dirs。
由于這一步過于繁雜瑣碎且容易出錯(都是辛酸淚),建議大家直接到文章開頭的Gitee鏈接里拉取根目錄下的BUILD.gn文件,放到lvgl根目錄即可。
修改報錯
這時候進行編譯的話,會發現報錯:lv_theme_default.c未定義lv_win_class。在lvgl工程里,lv_win.h里面已經將lv_win_classextern了,但好像lv_theme_default.c文件還是報錯未定義lv_win_class,于是我便直接在這個文件applications/sample/wifi-iot/app/lvgl/src/extra/themes/default/lv_theme_default.c中加入。
結合屏幕配置lvgl驅動
本次實驗使用一塊SSD1306的單色0.96寸顯示屏,分辨率是128*64.主要是方便驗證lvgl的可行性,大致流程如下:
這塊屏幕參考了連志安老師的OLED屏幕開發,將源碼中的SSD1306文件夾復制到lvgl目錄下:
配置lv_conf文件
修改lvgl根目錄下的lv_conf.h文件。
加入以下代碼,分別對應了屏幕的長和寬。
修改#define LV_COLOR_DEPTH 16為#define LV_COLOR_DEPTH 8.此選項為屏幕的色深。
(我嘗試過修改成1單色色深,但1的輸出只有純白色了,于是將這一步先設為8位色深,主要是我以后用的都是彩色屏幕,所以對此步驟并沒有硬性要求一定適配單色屏幕,此次先驗證可行性)。
設置內存大小,按照需求設置,一般來說20Kb夠用了(大工程除外)。
若是想要顯示CPU占用率、內存占用率、幀率,可以配置下圖兩個宏定義為1。
配置lvgl屏幕驅動
屏幕驅動的文件為這個applications/sample/wifi-iot/app/lvgl/examples/porting/lv_port_disp_template.c。
最首先我們要在這個文件加入屏幕驅動的頭文件引用。
lvgl精華所在便是它只需要屏幕的畫點API即可完成操作,這種低耦合性使得它非常便于移植。
SSD1306的畫點API在ssd1306.h中。
修改void lv_port_disp_init(void)屏幕驅動初始化函數。
lvgl官方提供了三種緩存模式,想要詳細了解的可以在官網查詢相關資料,本文章不過多贅述,我們本次使用了單緩存模式,其余兩種模式注釋掉即可.也由于屏幕比較小,所以緩存大小便是屏幕大小。
lvgl的繪圖實現函數static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p),用于圖形填充.我們需要在這里實現繪圖功能,SSD1306的畫點APIssd1306_DrawPixel將在這里被調用,SSD1306繪圖完成后還需要調用刷新函數ssd1306_UpdateScreen();才可以將屏幕刷新.(當然,如果有更加高效快速的刷新方式也可以使用,并不一定是不斷畫點的形式刷新)。
在前文中,我們將lvgl設置成8位色深模式,所以我們這里要稍加做判斷,但顏色小于100時,我們把它當成黑色,大于100時,我們把它當成白色.由此實現單色顯示。
顯示測試
在lvgl根路徑創建ssd1306_demo.c,在里面實現ssd1306的初始化以及lvgl的初始化,還有lvgl需要一直不斷循環的定時器和執行函數,定時器需要在執行函數之前。
需要注意的是此定時器和執行函數可以分成兩個線程執行,但如果這么做,需要為這兩個線程加上互斥鎖,并且定時器的間隔時間需要比執行函數的間隔時間短。
如果遇到lv_task_handler()執行函數堵死,大概率是內存沒分配夠,將線程的內存分配和lvgl的內存分配調大即可。
本次移植到這里就告一段落了,等下一階段有空了再做按鍵的使用。
文章相關附件可以點擊下面的原文鏈接前往下載:
https://ost.51cto.com/resource/2672。