1. 硬體和環境說明

执念执战發表於2024-06-10

說明:

端午在家宅,進行了LVGL的多端移植測試。

  • 目標是使用Squreline繪圖生成的同一段程式碼,實現在PC端、安卓端、彩屏微控制器端、單色屏微控制器端四端顯示。最終目標我是想實現在任意一端操作介面,其他幾端都能實現同步變化。

  • 目前已經實現了四端的簡單顯示:

  • 安卓手機端、墨水屏手機、微控制器彩屏端、微控制器單色黑白屏端:

  • Windows端:

  • 我手頭上也有幾款能用於移植演示的linux開發板,但由於我的老電腦壞掉了,新的電腦環境配置還沒裝,所以嵌入式Linux就還沒弄。但是想來也是一樣的效果。

簡單教程

1. 硬體和環境說明

目前使用的硬體如下:

  1. 安卓:使用了一款電子墨水屏手機,一款普通手機,開發環境為AndroidStudio
  2. 微控制器彩屏開發板,是ArtinChip基於D133CBS的崑崙派開發板,解析度480*272,帶觸控
  3. 微控制器單色屏開發板,是我自己畫的板子,可以放單色電子墨水屏和一款魚鷹光電的2.9寸類墨水屏高反TFT單色屏,圖上的是魚鷹光電的屏。電子墨水的屏之前驅動沒問題,電路板其實還有幾塊,但是懶得裝了,就沒放上去測試。目前的微控制器是STM32F401,後續會換成HC32F460晶片(板子也畫好了,程式也調過,但是可能我買了假的晶片,燒寫幾次就報廢燒不進去了,所以懶得焊接了,已經放在一邊好久了,上班都沒心情焊板子,更別說下班了,哈哈)。
  4. 桌面端使用Code::Blokcs的LVGL模擬器環境

2. 使用SquareLine建立一個簡單的頁面

  • 在[SquareLine]頁面下載並安裝的最新軟體。

  • 它有30天的免費試用期。

  • 然後,首先建立一個新的工程,儲存到你能找到的檔案地址中,然後設定解析度,我設定的是480*320,這個可以自行根據需要來,畢竟是測試。介面如圖:

  • 中文的匯入方式:

    • 首先,在電腦中搜尋.ttf格式的字型檔檔案,選一個你要用的中文字型檔,將它複製到上面儲存的檔案地址中的assets資料夾下
    • 然後在介面上點選右側的font介面,此時可以重新整理出剛剛複製的字型庫,然後在Symbols文字框中輸入你需要的中文字型

    此處我還沒搞清楚怎麼樣支援外部flash的字型檔,後續我會根據需要搞一下。因為我最終是想實現一個文字閱讀器的,不可能只顯示極個別的中文。

    • 然後就可以使用中文了:

    • 點選Export來匯出檔案,第一次需要選擇儲存點,此處我們建立一個ui資料夾,用於放匯出的檔案。這個資料夾就是後面我們需要用到的檔案。

      注意:直接複製ui檔案的話,有些地方需要改路徑,比如 #include "lvgl/lvgl.h"會報錯,改為 #include "lvgl.h" 即可。具體的請自行根據實際情況判斷處理。

3. PC客戶端移植

  • 使用LVGL官方教程,有一個 Code::Blocks的模擬器教程:從 [Simulator on PC] 頁面跳轉到 [code::blocks]頁面,根據教程一步一步來,先下載codeBlocks,然後下載當前git,再下載lvgl包,解壓到對應資料夾,再使用codeBlocks開啟工程,然後一步步直到編譯透過。
  • 但是官網的是最新的9.1版本的LVGL,所以內部只有一個lvgl資料夾,不需要像這個教程一樣下載多個。
  • 以上環境搭建好,並且能夠編譯執行,正常跳出LVGL介面後,說明環境搭建完成。此時其實執行後會顯示一個命令列的黑框,在 [build->select target]中選擇Release版本就沒有了。但是新的環境選擇release版本會報錯,我以前在公司的環境解決過,好久沒弄,忘記怎麼弄了,家裡面的環境還是報錯。先不管它了。
  • 然後將SquareLine生成的ui資料夾複製到codeblocks工程檔案所在目錄,然後在codeBlocks中對工程下的資料夾右擊,選擇 Add files recursively 來快速匯入ui下所有的檔案:

然後將ui/ui.c中的 ui_init() 替換掉之前main函式中的的LVGL的相關函式,然後包含相關的標頭檔案,再次編譯,修改程式碼直到編譯成功即可執行看效果。

注意,SquareLine只能選擇8.6或是8.11版本的LVGL,而codeblocks下載的LVGL大機率是最新版V9.0的,所以內部有些函式是不相容的,主要報錯例如:
error: unknown type name 'lv_scr_load_anim_t'; did you mean 'lv_screen_load_anim_t'?|
則是由於新的函式命名不同,可以按照後面的提示,改為 lv_screen_load_anim_t 即可(其他還有 lv_screen_load_anim 等也類似處理)。

還有一個報錯是:undefined reference to `lv_mem_free',改為 lv_free 即可。
其他的錯誤自行處理。

如果報錯位置類似於:

#if LV_COLOR_DEPTH != 16
    #error "LV_COLOR_DEPTH should be 16bit to match SquareLine Studio's settings"
#endif

可以直接遮蔽掉中間的 #error 預編譯指令,或者自行更改對應程式的LVGL配置。

一切無誤後,點選執行則會實現與SquareLine中繪製的同樣的介面(如果不是的話,可能是配置中的介面大小不同,找一下配置一下即可)。

本來想移植為與SquareLine同樣版本的LVGL的,但是移植了半天,還是沒成功,直接替換LVGL資料夾的話,最後有個.cbp的工程檔案需要處理,沒時間搞明白它了,就先放著。

4. 安卓端

安卓端我是參考的 [LVGL-在安卓上的移植].

    • 首先安裝[AndroidStudio],搭建好必要的環境後,它會自行安裝一些環境包。(寫安卓我是業餘的,雖然很久之前就開始用AndroidStudio寫過安卓程式了,還學過寫小遊戲,但是一直沒做過專案,都是自己玩,所以很水,時間長了就忘了,頁面只會用原生的拖拽控制元件實現,也沒學控制元件美化,很醜,所以想看看移植LVGL後效果怎麼樣,如果還可以的話就多用LVGL寫介面)。
  • 前期我是移植編譯不透過,然後胡亂按了一下 Ctrl+F5 還是 Ctrl+F9來著,它自己就把一些包下載好了。前期還會一個版本的錯誤,直接在 build.gradle 中將 minSdkVersion 由19改為21 就能用了
  • 一切編譯透過後,插上手機,正確識別後(多數手機現在都需要開啟開發者模式,允許USB除錯。魅族手機是需要在 [設定 -> 我的手機 ]中連續點選 系統版本 5次,然後就可以在設定的附中功能中找到開發者選項,並開啟USB除錯。海信手機是在[設定->關於手機]中連續點選 核心版本 號,就能開啟開發者模式。其他手機自行查詢)即可點選執行除錯。一切順利後就能執行其編寫的測試程式了。
  • 執行成功後,即可移植我們自己的ui程式。
  • 將ui資料夾直接複製到安卓工程所在資料夾下的 lvgl-android\app\src\main\cpp 資料夾下,與LVGL放在同一資料夾下(其他資料夾也行,自行處理),然後用 ui_init() 替換之前的程式碼,包含標頭檔案,一切正確後即可編譯透過,然後用虛擬機器或是實際手機就可以檢視效果了,觸控也能用。
  • 由於手機解析度高,480*272螢幕下繪製的各種控制元件看起來很大,但是放到手機中就非常小了,所以解析度的適配還是一項很繁雜的功能,因為SquareLine生成的程式碼都是絕對地址,而且是畫素級別的,所以如果想適配螢幕,要麼重新用SquareLine繪製對應螢幕大小的控制元件,要麼自己手動更改每一個控制元件的值。

5. MCU端

  硬體使用的是ArtinChip的基於D133的崑崙派。這個晶片速度是480MHz,但是實際上跑LVGL跑分結果普遍在60-70FPS,而同樣速度的STM32H750,同樣的480*272的螢幕,我記得跑速普遍在180FPS(具體記不清了,以前在公司買的開發板上跑過),不知道是它沒最佳化好還是真的就那麼大差距。

  • 它的資料都在 [ArtinChip],按照教程下載檔案包和下載工具後就能用了,環境都包含好了。裡面也有各種開發教程。

  • 將ui資料夾複製到packages的lvgl-ui資料夾下。由於使用的是RTT的scons編譯環境,所以需要構建編譯鏈,用的是SConscript指令碼。

  • 直接複製lvgl-ui下的SConscript檔案到 ui 資料夾下,將if GetDepend 下面的 src += Glob('xxx)部分修改,增加ui資料夾下的所有.c檔案的路徑,然後就能編譯透過了。將aic_ui.c中的demo部分的函式直接替換為ui_init() 幷包含ui.h標頭檔案,即可完成修改。編譯後下載就能看到效果圖,觸控也能用。

  • 單色屏則需要首先實現單色屏的畫點、刷屏函式。由於使用的單色屏它的重新整理很慢,如果直接將畫點函式和局刷函式移植到LVGL對應的介面上,效果很不好,會頻繁的局刷,整屏顯示要刷好久。所以將對應的函式繫結到向緩衝區畫點,然後使用判斷是否完成緩衝區的畫點,完成後使用訊號量來通知將緩衝區填充到螢幕,即可實現較為流暢的刷屏了。
    另外由於是單色屏,所以需要根據顏色範圍判斷需要畫黑點還是白點,以是否大於0x8FFF(使用16位色繪圖時)來判斷,就可以實現有效區分(實際上,繪圖時只用了0xffff和0兩種顏色,但是LVGL渲染字型時,部分畫素會變淺,所以不能用0或0xFFFF來判斷)

  • 這個單色屏裝置是我當時想做一款電子單詞卡的專案,當時剛畢業沒多久,軟硬體功底都很一般,摸索著完成了。當時純用裸機和手寫介面,完成了選單、TF卡文字閱讀、單詞卡展示切換等比較完善的功能。但是當時程式碼寫的比較LOW,介面也是純手繪,很LOW,硬體走線也很一般,本來一直想開源的,後面想想還是製作好一點再開源吧。結果這一拖就是好幾年,專利沒交錢也過期了。現在滿大街都是電子單詞卡,當年我做完了市場上都是沒有的。
    現在想著,用LVGL做一個多端同步的裝置,可以做很多好玩的東西,就不單單是一個電子閱讀器了。

  • 另外,單色屏解析度是 168*384,使用ui中的檔案它會顯示中間部分,所以圖上控制元件放到中間單色屏上才能顯示。

  • 這款螢幕其實很奇怪,當時我買來時,它只有一個全屏刷圖的例子,圖片的解析度很低。畫點只能畫一個矩形塊!!經過我的嘗試,才發現,它一個畫素,前六位表示6個畫素點,還是交叉排列的,後面兩位是沒用的!!就很奇葩的設計。估計他們的工程師也沒調出來單個畫素的畫點,後面我搞定了。它清晰度是比同為2.9寸的電子墨水屏要高一些(電子墨水屏的解析度是128*296的),但是反光效果不太好,有點像鏡子,導致強光下燈珠都能看到,暗光下啥都看不到,所以需要找到角度才能看到,墨水屏在這方面會稍微強一點。二者重新整理率都差不多,這個屏會快一些,但是會有很明顯的捲簾現象,問了廠家也解決不了(可能是他們不上心),我也懶得看手冊,先這麼用吧。

結尾

首先得感謝上面我參考的一些文章作者。
對於多螢幕的快速適配我還需要多花點時間研究研究LVGL,比如安卓的解析度較高,效果就不好,而且不同解析度的螢幕顯示大小也不同。而且安卓不是全屏,有框和提示,後面有時間我需要最佳化一下,爭取多端都做到無邊框。
還有就是PC端由於是9.0的LVGL版本,所以程式不是完全相容,後面需要降級最佳化一下。

這次程式就不放了,因為分類太多,而且程式碼也沒有幾行需要自己寫的,按照教程自行體驗即可。

後面想做不少東西,順便看看能不能用來掙點錢。馬上要離職了,年紀也不小了,整天就玩玩板子寫程式,拿著點工資,老婆都找不著,唉,得多考慮搞錢了,有錢才能找老婆,沒錢只能打光棍。

本文水平有限,內容很多詞語由於知識水平問題不嚴謹或很離譜,但主要作為記錄作用,能理解就好了,希望以後的自己和路過的大神對必要的錯誤提出批評與指點,對可笑的錯誤不要嘲笑,指出來我會改正的。

另外,轉載使用請註明作者和出處,不要刪除文件中的關於作者的註釋。

隨夢,隨心,隨願,恆執念,為夢執戰,執戰蒼天! ------------------執念執戰

相關文章