當前位置:首頁 > 公眾號精選 > 裸機思維
[導讀]在前面的文章《【喂到嘴邊了的模塊】準備徒手擼GUI?用Arm-2D三分鐘就夠了》中,我們介紹了如何借助 cmsis-pack 快速的在 MDK 中部署 arm-2d。

【說在前面的話】


在前面的文章《【喂到嘴邊了的模塊】準備徒手擼GUI?用Arm-2D三分鐘就夠了》中,我們介紹了如何借助 cmsis-pack 快速的在 MDK 中部署 arm-2d。
在過去的一段時間內,想必很多人都完成了部署,看到了下面的畫面吧?


如果還沒有,推薦先跟著上一篇文章的手把手圖文教程——完成基本的部署吧。本文將在此基礎上繼續(xù)為您介紹如何使用arm-2d來簡化我們手擼GUI的過程。

為了避免讓大家產生疑惑,這里我們需要再次明確一下我們所要面對的開發(fā)環(huán)境:
  • 資源相對緊張的MCU,無法負擔起傳統(tǒng)的嵌入式GUI(比如以體積“小巧”著稱的LVGL):
    • Flash <= 64K,或者
    • 應用本身已經占用了大量Flash空間,留給GUI的空間非常有限
    • SRAM <= 16K
  • 需要實現的GUI界面較為簡單(這點在隨后會詳細介紹)
  • 幀率要求較低(傳說中的8幀不卡、9幀流暢、10幀電競)


【基于面板的界面設計】


從用戶的角度來說,如果一個嵌入式產品帶了彩屏,很自然的就會希望它能提供像智能手機(或平板設備)一樣的操作體驗——但從開發(fā)者的角度來說,用戶的這一期望往往會被錯誤的理解為:用戶希望嵌入式產品上的圖形界面能像手機那樣支持“這樣或那樣”的滑動、滾動效果——如果能做到當然最好,但其實這并不是這些“類智能手機界面”設計的核心。
讓我把話挑明了吧——流暢的滑動只是添料,甚至是可以完全丟棄的——真正核心的是一套與傳統(tǒng)Windows圖形界面設計完全不同的理念。關于這套設計理念,有一套叫做“人本界面”的設計方法論作為支撐,感興趣的小伙伴可以在豆瓣上搜索同名的圖書。

就本文要討論的內容來說,我們可以簡單的關注以下的一些要點:

  • 智能設備的界面強調“簡潔”、并希望“讓用戶的注意力一次只集中在一件簡單的事物上”。
基于這一原則,又派生出了如下的特點:
  • 與Windows不同,智能設備的界面很少(或者極力避免)窗口重疊
  • 界面的基本單位不是“窗體(Window)”,而是以整個屏幕為基本單位的“面板(Panel)”
  • 每個面板的內容都盡可能簡單、通過留白的方式強調那些需要用戶注意的內容;
  • 每個面板的功能都盡可能單一:
    • 一般避免在同一個面板中擠進多個不太相關的功能;
    • 相關的內容,如果能夠放得下,且美觀,則可以有主次的布置在同一個面板中以減少用戶切換面板帶來的不便;
    • 如果相關的內容如果無法在同一個面板中展示,則一定會添加快捷方式方便用戶快速進行面板的切換;
  • 面板間的切換方式以大家熟悉的PPT頁面切換方式類似
    • 對滑動切換來說,要么不做,要做就要“絲滑”(差不多30FPS),否則會給用戶帶來“卡頓”的不適感
    • 完全沒有動畫的切換往往會給用戶“設備反應迅速”的錯覺,對負擔不起高幀率的嵌入式設備來說,反而是最好的選擇

仔細回想一下,身邊的智能設備,是不是都基本滿足上述特點?——其實我們熟悉的手機和平板也是如此。


基于上述原則,我們甚至可以總結出一套簡單有效的“嵌入式界面設計八股”:

  • 用戶界面分成三個部分:狀態(tài)面板、導航面板功能面板
  • 狀態(tài)面板又叫待機面板,用于顯示狀態(tài)信息(比如溫度、時間、產品Logo、產品當前狀態(tài)等等)。
    • 通常在待機界面上按下任意鍵(或者進行任意觸摸)進入導航面板
    • 一般用戶超過一段時間沒有與界面進行交互后會自動進入狀態(tài)面板,所以狀態(tài)面板有時候又叫待機面板
  • 導航面板:也就是大家常說的菜單。
    • 一般導航面板以圖標、列表或者按鈕的形式存在,
    • 一般避免超出屏幕范圍的內容,最好做到讓用戶對所有選項“盡收眼底”
    • 導航面板可以通過子面板的形式實現多級菜單,從而簡化開發(fā)
  • 功能面板:實現具體功能的面板,一般由導航面板進入
    • 每個面板的功能都盡可能單一,比如專門設置溫度、專門設置時間等等
    • 相關的導航面板之間可以通過類似左右箭頭(或者底部導航快捷按鈕)的機制進行快捷切換




【什么是場景(scene)】


“場景(scene)”是 arm-2d為“手擼GUI”的用戶引入的一個概念,通過配套的“場景播放器(scene player)”,極大的簡化了基于面板的界面開發(fā)。
一般來說,一個簡單的面板用一個場景就可以搞定;而稍微復雜點的面板則可以通過多個場景(以及基于狀態(tài)機的場景切換)來搞定——總的原則就是,無論多復雜的面板,都可以拆分成一個個簡單的場景來分而治之。
也許你已經注意到了:原本面板本身就已經很簡單了,那么所謂“復雜的面板”根據狀態(tài)機拆分成多個場景后是不是更加簡單了?——是的,每個場景的功能都是極其單一和簡單的——極大的簡化了每個場景的實現難度。


舉個例子:有個面板的功能是設置溫度,當超過某一特定值后,需要彈出一個窗口提醒用戶當前設置值有某些注意事項。這樣的面板在設計時就可以拆分成兩個場景:1)一個正常的數值設置場景,實現一個類似滑條的功能讓用戶設置溫度;2)一個專門的場景來提示用戶注意事項——通過這樣的安排,每個場景都可以非常單一。再比如:某個面板的用來設置多個相關的選項,并且當用戶開啟某個開關后,會出現一些隱藏選項(或者原本不可設置的選項變成可選)。此時,就可以根據這個開關的狀態(tài),引入兩個場景:一個對應開關關閉時的面板,一個對應開關開啟時的面板——總之,面板拆的越細致,每個場景的設計就越簡單


【場景(scene)的數據結構和構成】


場景在 arm-2d 中以類 arm_2d_scene_t 來描述:
/*! * \brief a class for describing scenes which are the combination of a *        background and a foreground with a dirty-region-list support *  */typedef struct arm_2d_scene_t arm_2d_scene_t;struct arm_2d_scene_t { arm_2d_scene_t *ptNext; //!< next scene arm_2d_scene_player_t *ptPlayer; //!< points to the host scene player arm_2d_region_list_item_t *ptDirtyRegion; //!< dirty region list for the foreground  arm_2d_helper_draw_handler_t *fnBackground; //!< the function pointer for the background  arm_2d_helper_draw_handler_t *fnScene; //!< the function pointer for the foreground void (*fnOnBGStart)(arm_2d_scene_t *ptThis); //!< on-start-drawing-background event handler void (*fnOnBGComplete)(arm_2d_scene_t *ptThis); //!< on-complete-drawing-background event handler void (*fnOnFrameStart)(arm_2d_scene_t *ptThis); //!< on-frame-start event handler void (*fnOnFrameCPL)(arm_2d_scene_t *ptThis); //!< on-frame-complete event handler  /*! * \note We use fnDepose to free the resources */ void (*fnDepose)(arm_2d_scene_t *ptThis); //!< on-scene-depose event handler struct { uint8_t bOnSwitchingIgnoreBG    : 1; //!< ignore background during switching period uint8_t bOnSwitchingIgnoreScene : 1; //!< ignore forground during switching period };};


其數據結構并不復雜。



數據結構的主體是這兩個指針:

  • fnScene:指向一個由用戶提供的繪圖函數:

    • 繪制一個場景中所有的內容;或者

    • 當場景中存在“不會變化且不會被覆蓋的背景”和“少數”內容會發(fā)生變化的前景時,專門用于繪制前景——此時就需要通過ptDirtyRegion來指向描述前景變化區(qū)域的臟矩陣(Dirty Region List)。


  • fnBackground:指向一個由用戶提供的繪圖函數,專門繪制一個場景中那些“只需要繪制一次”且“未來不會被前景覆蓋或者變化”的內容,最典型的就是繪制場景中的背景圖片;


需要特別說明的是:

  • fnBackground 只會在繪制每個場景的第一幀時調用;

  • 隨后的每一幀就只會調用 fnScene

  • fnBackground 會繪制整個屏幕;

  • 臟矩陣(ptDirtyRegion)只對 fnScene 有效;

  • 當ptDirtyRegion 為 NULL時,fnScene也是繪制整個屏幕。

    • 這意味著,當 ptDirtyRegionNULL時,fnBackground 繪制的內容會 100% 被覆蓋掉——也就是說完全沒用。這意味著:

    • 當且僅當我們指定了有效的臟矩陣時,fnBackground 才是實際有意義的


如果你對“背景”和“前景”的分工感到似懂非懂,不妨看下面這個例子:



在這個場景中:

  • 作為背景的狗頭實際上不會發(fā)生變化,因此我們只需在 fnBackground 所指向的繪圖函數中繪制即可;

  • 動態(tài)進度條由于其內容一直在變化,因此需要在 fnScene所指向的繪圖函數中“配合臟矩陣”進行重復繪制。


為了方便應用開發(fā),arm_2d_scene_t 提供了一系列事件處理程序接口(回調函數),它們與背景、場景的繪制關系如下:


可以看到,這里的事件處理順序并不復雜,大家可以根據實際的應用需求各取所需。

【場景播放器(scene player)的本質是什么】
場景播放器的本質是一個針對場景(scene)的隊列(FIFO):


  • 用戶可以預先生成多個場景,并通過函數arm_2d_scene_player_append_scenes壓入隊列中;
  • 隊列的頭部就是當前生效的場景;
  • 用戶可以在任意時刻通過函數arm_2d_scene_player_switch_to_next_scene來安全的觸發(fā)場景切換,
    • 所謂的場景切換就是丟棄隊列當前的頭部場景——換成下一個;
  • 場景切換后,被丟棄的場景會調用 fnDepose ,用戶可以利用這個函數為對應場景“擦屁股”
    • 比如,假設一個場景(arm_2d_scene_t)對象本身就是動態(tài)分配的(從 malloc中分配),那么就可以通過 fnDepose 方法來將內存釋放掉(比如調用 free函數)。
  • 場景播放器提供了 arm_2d_scene_player_flush_fifo 方法,它會清空整個隊列。
    • 被清空出去的場景都會被依次調用 fnDepose,因此不用擔心內存泄露的問題。
  • 場景切換是支持特效的,比如:淡入淡出、滑動和擦除等等


【用場景開發(fā)也太簡單了8!】


前面洋洋灑灑的做了這么多理論鋪墊,也許會讓你對 scene 的使用產生了“非常復雜”的錯覺或者擔憂,但實際情況卻相反:借助cmsis-packRTE的幫助,創(chuàng)建 scene 幾乎只要點幾下鼠標就可以搞定,而且立即就可以使用。
假設你已經根據《【喂到嘴邊了的模塊】準備徒手擼GUI?用Arm-2D三分鐘就夠了》的描述,完成了 arm-2d 的部署,并且成功的加入了一個 Display Adapter,此時我們應該能看到這樣的效果:


此時,打開 RTE,展開Acceleration后在Arm-2D Helper中找到 Scene


如果你的界面中找不到 Scene,說明你的 arm-2d cmsis-pack 版本較老,可以關注公眾號【裸機思維】后,發(fā)送關鍵字 arm-2d 后獲取最新版本的網盤鏈接。

Scene的右邊,我們可以通過“增加數值”的方式向工程中添加指定數量的場景。單擊確定后,對應數量的場景模板會加入到工程管理器中:


這里的 arm_2d_scene_0.harm_2d_scene_0.c 分別對應我們新加入的場景的頭文件和源代碼。


打開 main.c,加入對場景的頭文件引用:
#include "arm_2d_scene_0.h"

其實,所謂的 Display Adapter 就是場景播放器(arm_2d_scene_player_t):

ARM_NOINITexternarm_2d_scene_player_t DISP0_ADAPTER;

在初始化完 Display Adapter 后,我們調用場景的初始化函數arm_2d_scene0_init()——將它們加入指定的場景播放器隊列中:

#include "arm_2d_scene_0.h"...int main (void) { arm_irq_safe { arm_2d_init(); }   disp_adapter0_init();  arm_2d_scene0_init(&DISP0_ADAPTER);  while(1) { disp_adapter0_task(); }  }

調用函數 arm_2d_scene_player_switch_to_next_scene() 來切換到我們新加入的場景中:

#include "arm_2d_scene_0.h"...int main (void) { arm_irq_safe { arm_2d_init(); }   disp_adapter0_init();  arm_2d_scene0_init(&DISP0_ADAPTER); arm_2d_scene_player_switch_to_next_scene(&DISP0_ADAPTER);  while(1) { disp_adapter0_task(); }  }


為了方便觀察效果,不妨設置一個場景切換效果:


#include "arm_2d_scene_0.h"...int main (void) { arm_irq_safe { arm_2d_init(); }   disp_adapter0_init();  /* 初始化場景 scene0,并將其加入到場景播放器 DISP0_ADAPTER 中 */ arm_2d_scene0_init(&DISP0_ADAPTER);  /* 設置切換特效為 淡入淡出(白色) */ arm_2d_scene_player_set_switching_mode(  &DISP0_ADAPTER, ARM_2D_SCENE_SWITCH_MODE_FADE_WHITE); /* 設置切換持續(xù)時間為 3000ms */ arm_2d_scene_player_set_switching_period( &DISP0_ADAPTER,  3000);  /* 申請切換到新加入的場景中 */ arm_2d_scene_player_switch_to_next_scene(&DISP0_ADAPTER);  while(1) { disp_adapter0_task(); }  }  

編譯后運行,可以看到類似如下的效果:



可以看到,場景播放器從默認的“轉圈圈”界面以“漸明漸暗”的形式切換到了我們的新場景 scene0 中。



細心的小伙伴可能很快就注意到了一個奇怪的地方:為啥很快 scene0 又消失在白屏中了呢?要解答這一疑問不妨打開
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯合牽頭組建的NVI技術創(chuàng)新聯盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現場 NVI技術創(chuàng)新聯...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉