針對 R128 平臺,提供了LVGL作為圖形系統(tǒng)。
LVGL 說明
LVGL 是一個免費的開源圖形庫,提供了創(chuàng)建嵌入式GUI 所需的一切,具有易于使用的圖形元素,美觀的視覺效果和低內(nèi)存占用,采用MIT 許可協(xié)議,可以訪問LittlevGL官網(wǎng)獲取更多資料。
- 強大的構(gòu)建塊:按鈕、圖表、列表、滑塊、圖像等。
- 高級圖形引擎:動畫、抗鋸齒、不透明度、平滑滾動、混合模式等。
- 支持各種輸入設(shè)備:觸摸屏、鼠標、鍵盤、編碼器、按鈕等。
- 支持多顯示器。
- 獨立于硬件,可與任何微控制器和顯示器一起使用。
- 可擴展以使用少量內(nèi)存(64 kB 閃存、16 kB RAM)運行。
- 多語言支持,支持UTF-8 處理、CJK、雙向和阿拉伯語。
- 通過類CSS 樣式完全可定制的圖形元素。
- 受CSS 啟發(fā)的強大布局:Flexbox 和Grid。
- 支持操作系統(tǒng)、外部內(nèi)存和GPU,但不是必需的。
- 使用單個幀緩沖區(qū)也能平滑渲染。
- 用C 編寫并與C++ 兼容。
- Micropython Binding 在Micropython 中公開LVGL API。
- 可以在PC 上使用模擬器開發(fā)。
- 100 多個簡單的例子。
- 在線和PDF 格式的文檔和API 參考。
目前RTOS 中移植了LVGL 8.1.0 核心組件與Demo,下表列出LVGL 相關(guān)庫說明:
包名
說明
lv_demos
lvgl的官方demo
lv_drivers
lvgl的官方設(shè)備驅(qū)動程序,集成了sunxifb、sunxig2d和sunximem
lv_examples
lvgl測試用例,最終調(diào)用的是lv_demos中的函數(shù)
lvgl
lvgl核心庫
lv_g2d_test
g2d測試用例,專門測試已經(jīng)對接好的g2d接口
lv_monitor
壓力測試與狀態(tài)監(jiān)測軟件
sunxifb.mk
公共配置文件,寫應(yīng)用Makefile時需要包含進去
LVGL 配置
mrtos_menuconfig
配置如下
System components --- >
thirdparty components --- >
[*] Littlevgl-8 --- >
[*] lvgl examples (lvgl官方demo)
[] lvgl g2d test (g2d 接口測試用例)
[*] lvgl-8.1.0 use sunxifb double buffer (使能雙緩沖,解決撕裂問題)
[*] lvgl-8.1.0 use sunxifb cache (使能fb cache)
[] lvgl-8.1.0 use sunxifb g2d (使能G2D硬件加速)
[] lvgl-8.1.0 use sunxifb g2d rotate (使能G2D硬件旋轉(zhuǎn))
[] lvgl-8.1.0 use freetype (使能freetype)
LVGL 框架
LVGL 源碼位于 lichee/rtos-components/thirdparty/littlevgl-8
, 其框架如圖:
SunxiFB
在 sunxifb
中,我們提供了一組顯示接口,如下:
接口
說明
sunxifb_init
該函數(shù)主要功能是初始化顯示引擎。帶一個旋轉(zhuǎn)參數(shù),使能g2d旋轉(zhuǎn)的話,就用這個參數(shù)指定旋轉(zhuǎn)方向
sunxifb_exit
該函數(shù)比較簡單,實現(xiàn)關(guān)閉cache
,關(guān)閉g2d
,釋放旋轉(zhuǎn)buffer
,關(guān)閉fb0
sunxifb_flush
該函數(shù)比較重要,負責把draw buffer
拷貝到back buffer
中,并且繪制最后一幀后,交換front
與back buffer
。應(yīng)用不要調(diào)用該函數(shù)
sunxifb_get_sizes
該函數(shù)獲取屏幕分辨率,這樣應(yīng)用程序就可以不用寫死初始化時的分辨率了
sunxifb_alloc
該函數(shù)主要用來申請系統(tǒng)繪圖內(nèi)存,使能部分g2d
功能后,會申請連續(xù)物理內(nèi)存
sunxifb_free
該函數(shù)用來釋放sunxifb_alloc
申請的內(nèi)存
代碼位置如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_drivers/display/sunxifb.c
在sunxifb_init(rotated)
,中rotated
的旋轉(zhuǎn)值可以為:
LV_DISP_ROT_NONE
,LV_DISP_ROT_90
,LV_DISP_ROT_180
,LV_DISP_ROT_270
。
最后還有賦值 disp_drv.rotated = rotated
。如果沒有g(shù)2d旋轉(zhuǎn),也可以指定disp_drv.sw_rotate = 1
使用軟件旋轉(zhuǎn)。
sunxig2d
在 sunxig2d
中,實現(xiàn)了對g2d``ioctl
的封裝,這些函數(shù)都 不需要應(yīng)用調(diào)用 ,但能加深對整個框架的理解,相關(guān)的接口如下:
接口
說明
sunxifb_g2d_init
g2d
模塊初始化函數(shù),打開 /dev/g2d
節(jié)點,設(shè)置 g_format
。初始化時,根據(jù)使能的宏,打印相應(yīng)的 log
sunxifb_g2d_deinit
該函數(shù)關(guān)閉 g2d
設(shè)備
sunxifb_g2d_get_limit
該函數(shù)獲取 g2d
使用閾值
sunxifb_g2d_blit_to_fb
該函數(shù)用來拷貝 fb0
的 front
和 back buffer
這兩塊 buffer
,也可以把 rotate buffer
旋轉(zhuǎn)到 back buffer
sunxifb_g2d_fill
該函數(shù)使用g2d填充一個顏色矩形,顏色可以帶透明度
sunxifb_g2d_blit
該函數(shù)用來拷貝圖像,不能 blend
圖像
sunxifb_g2d_blend
該函數(shù)可以進行圖像 blend
sunxifb_g2d_scale
該函數(shù)用來縮放圖像
代碼位置如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_drivers/display/sunxig2d.c
以上 g2d
函數(shù),都已經(jīng)對接 lvgl
繪圖框架,使用 lvgl
的 lv_draw_map
、lv_img_set_zoom
和 lv_canvas_draw_img
函數(shù)就可以使用起來。
lv_g2d_test
應(yīng)用中有完整的使用示例。
sunximem
在sunximem
中,實現(xiàn)了管理物理內(nèi)存的封裝,這些函數(shù)都 不需要應(yīng)用調(diào)用 ,但能加深對整個框架的理解,如下:
接口
說明
sunxifb_mem_init
該函數(shù)會在sunxifb_init
中調(diào)用,初始化物理內(nèi)存申請接口,使用的是 libuapi
中間件
sunxifb_mem_deinit
該函數(shù)通過調(diào)用 SunxiMemClose
,釋放申請的接口資源
sunxifb_mem_alloc
該函數(shù)比較重要,許多地方都會用到,需要傳入申請的字節(jié)數(shù)和使用說明
sunxifb_mem_free
該函數(shù)用來釋放調(diào)用 sunxifb_mem_alloc
申請的內(nèi)存
sunxifb_mem_get_phyaddr
該函數(shù)把 sunxifb_mem_alloc
申請內(nèi)存的虛擬地址轉(zhuǎn)換為物理地址,g2d
驅(qū)動只接受 buffer
的物理地址或者fd
sunxifb_mem_flush_cache
該函數(shù)用來刷 sunxifb_mem_alloc
申請buffer
的 cache
代碼位置如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_drivers/display/sunxigmem.c
因為g2d
驅(qū)動只能使用物理連續(xù)內(nèi)存,因此解碼圖片時,必須要通過 sunxifb_mem_alloc
來申請內(nèi)存。
當前只實現(xiàn)了bmp、png和gif圖片的內(nèi)存申請,jpeg圖片暫未實現(xiàn)
當使用 lv_canvas_set_buffer
時,傳入的 buffer
需要是 sunxifb_alloc
申請的 buffer
,sunxifb_alloc
中會判斷是否需要申請物理連續(xù)內(nèi)存。
自定義畫布lv_canvas暫未對接g2d縮放功能
evdev
觸摸我們用的是lvgl
官方的evdev
代碼位置如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_drivers/indev/evdev.c
lvgl 使用觸控功能,需在應(yīng)用lv_drv_conf.h 文件中配置:
# define USE_EVDEV 1
應(yīng)用lv_drv_conf.h
中的EVDEV_NAME
要與所使用的觸摸屏驅(qū)動對應(yīng),例如 lv_examples
的配置文件:
lichee/rtos-components/thirdparty/littlevgl-8/lv_examples/src/lv_drv_conf.h
如果disp_drv.rotated 指定了旋轉(zhuǎn)90 或者180 度,lvgl 內(nèi)部會自行旋轉(zhuǎn)觸摸坐標,不用觸摸驅(qū)動內(nèi)部去旋轉(zhuǎn)觸摸坐標。
color depth
在應(yīng)用 lv_conf.h
文件中有關(guān)于色彩深度 LV_COLOR_DEPTH
的配置,例如 lv_examples
的配置文件:
lichee/rtos-components/thirdparty/littlevgl-8/lv_examples/src/lv_conf.h
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 32
使用SPI 屏顯示,應(yīng)用 LV_COLOR_DEPTH
必須和屏幕所支持的像素格式匹配;而其他類型的屏,應(yīng)用LV_COLOR_DEPTH
選擇 16 或32 都可正常顯示。
LV_COLOR_DEPTH
選擇16 位相較于32 位,內(nèi)存占用更小,幀率更快,但是色彩總數(shù)較少,顯示漸變顏色可能會過渡不平滑。
LVGL 新建應(yīng)用
推薦以 lv_g2d_test
為模板,復(fù)制一個新項目:
lichee/rtos-components/thirdparty/littlevgl-8/lv_g2d_test
在 Makefile
中,需要包含 sunxifb.mk
公共配置,在編譯應(yīng)用時會把宏傳遞下去。方式如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_g2d_test/Makefile
include components/common/thirdparty/littlevgl-8/sunxifb.mk
另外可以注意到有以下配置,這些配置需要按需開啟,在部分芯片上是不支持 G2D_BLEND
等操作的,只支持簡單的旋轉(zhuǎn)功能:
ifeq ($(CONFIG_LVGL8_USE_SUNXIFB_G2D),y)
CFLAGS+=-DLV_USE_SUNXIFB_G2D_FILL
-DLV_USE_SUNXIFB_G2D_BLEND
-DLV_USE_SUNXIFB_G2D_BLIT
-DLV_USE_SUNXIFB_G2D_SCALE
endif
在應(yīng)用編譯的實際 Makefile
中,可以只編譯需要的文件,縮減可執(zhí)行文件的大小。
關(guān)于lvgl 的配置文件,也是建議用 lv_g2d_test
中的,可以對比原始未修改過的配置,然后再根據(jù)實際場景開關(guān)相應(yīng)配置。配置文件如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_g2d_test/src/lv_conf.h
lichee/rtos-components/thirdparty/littlevgl-8/lv_g2d_test/src/lv_drv_conf.h
原文件:
lichee/rtos-components/thirdparty/littlevgl-8/lvgl/lv_conf_template.h
lichee/rtos-components/thirdparty/littlevgl-8/lv_drivers/lv_drv_conf_template.h.h
最后就是應(yīng)用的初始化了,在 lv_g2d_test
中,有比較清晰的調(diào)用流程了,需要注意的是 sunxifb_init
需要傳入旋轉(zhuǎn)參數(shù)和 sunxifb_alloc
申請內(nèi)存即可。
LVGL 運行
我們提供了幾個測試用例,執(zhí)行命令如下:
lv_examples 0, is lv_demo_widgets
lv_examples 1, is lv_demo_music
lv_examples 2, is lv_demo_benchmark
lv_examples 3, is lv_demo_keypad_encoder
lv_examples 4, is lv_demo_stress
在初始化時,會有如下打印,根據(jù)配置的不同會有差異,表示打開了某項配置:
wh=800x480, vwh=800x960, bpp=32, rotated=0
Turn on double buffering.
Turn on 2d hardware acceleration.
Turn on 2d hardware acceleration fill.
Turn on 2d hardware acceleration blit.
Turn on 2d hardware acceleration blend.
Turn on 2d hardware acceleration scale.
Turn on 2d hardware acceleration rotate.
LVGL 開啟觸控功能
lvgl
使用觸控功能,需在應(yīng)用 lv_drv_conf.h
文件中使能宏 USE_EVDEV
。前提要確認好觸摸屏驅(qū)動模塊能夠正常加載使用,并且使 lv_drv_conf.h
中的 EVDEV_NAME
與所使用的觸摸屏驅(qū)動對應(yīng):
# define USE_EVDEV 1
# define EVDEV_NAME "touchscreen"
lvgl 對接觸摸屏驅(qū)動的代碼位置如下:
lichee/rtos-components/thirdparty/littlevgl-8/lv_drivers/indev/evdev.c
LVGL 開啟 LOG
日志調(diào)試
lvgl 自帶的Log 日志調(diào)試功能,在應(yīng)用 lv_conf.h
文件使能宏 LV_USE_LOG
及相關(guān)配置:
#define LV_USE_LOG 1
#define LV_LOG_LEVEL LV_LOG_LEVEL_INFO
#define LV_LOG_PRINTF 1
另外在 sunxifb.c
文件或 Makefile
中定義宏 LV_USE_SUNXIFB_DEBUG
,可以 Log 打印出LVGL 實際刷圖顯示的幀率。
SPI 屏顯示 LVGL 畫面異常
應(yīng)用 lv_conf.h
文件中的LV_COLOR_DEPTH
要和SPI 屏所支持的像素格式匹配:
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 32
-
微控制器
+關(guān)注
關(guān)注
48文章
7896瀏覽量
153625 -
嵌入式
+關(guān)注
關(guān)注
5133文章
19502瀏覽量
314342 -
RTOS
+關(guān)注
關(guān)注
24文章
838瀏覽量
120699 -
GUI
+關(guān)注
關(guān)注
3文章
674瀏覽量
40690 -
LVGL
+關(guān)注
關(guān)注
1文章
99瀏覽量
3518
發(fā)布評論請先 登錄
使用全志R128實現(xiàn)LVGL的移植

R128點屏踩坑筆記

評論