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