在所有行業(yè)中大規模采用物聯(lián)網(wǎng)技術(shù)的結果是對嵌入式開(kāi)發(fā)技能的需求日益增加。然而,嵌入式開(kāi)發(fā)在歷史上一直是一個(gè)相當復雜的領(lǐng)域,人們不可能在一夜之間將其添加到技能中。
幸運的是,在過(guò)去的十年中,硅供應商在簡(jiǎn)化嵌入式開(kāi)發(fā)方面投入了大量的精力,特別是對于在該領(lǐng)域經(jīng)驗很少甚至沒(méi)有經(jīng)驗的人。但根據我的經(jīng)驗,至少有一個(gè)領(lǐng)域的工作仍然過(guò)于繁瑣:圖形用戶(hù)界面(GUI)開(kāi)發(fā)。許多應用程序至少需要某種圖形用戶(hù)界面:顯示器可能很小,單色,幾乎沒(méi)有任何按鈕供用戶(hù)按下,但它仍然是一個(gè)用戶(hù)界面,是嗎?
在本文中,我也將分享一些技巧和一些我用來(lái)幫助保持GUI開(kāi)發(fā)愉快的工具。
硬件集成和可移植性
大多數顯示設備都帶有示例代碼和驅動(dòng)程序,這些代碼和驅動(dòng)程序將使您至少能夠顯示某些內容。但是GUI不僅僅是一個(gè)屏幕,因為界面也是由輸入組成的,對嗎?那些按鈕、觸摸屏輸入和系統中可能參與交互的其他傳感器如何?
這看起來(lái)可能不多,但在受約束的系統上運行時(shí),正確處理簡(jiǎn)單的硬件輸入(如按下的按鈕)可能需要大量工作,并且您可能很快就不得不處理復雜的定時(shí)或中斷管理問(wèn)題。由于這些通常涉及低級編程,它們往往非常依賴(lài)硬件,不容易移植。
很多嵌入式開(kāi)發(fā)都是用C語(yǔ)言完成的,因此,除了低級的引導代碼外,嵌入式代碼在理論上是相當可移植的。然而,編寫(xiě)可移植GUI代碼是一個(gè)完全不同的故事,除非您在現有框架(如LVGL或Azure RTOS GUI)的基礎上進(jìn)行構建,否則需要花費大量精力來(lái)抽象所有硬件依賴(lài)項,在嘗試保持*佳狀態(tài)時(shí)更是如此。
當然,并非總是有必要(或可能)擁有*可移植的GUI代碼。然而,在這個(gè)全球芯片短缺的時(shí)代,它可以被證明是非常方便的,不需要對特定類(lèi)型的微控制器或LCD顯示器有嚴格的依賴(lài)。
內存管理
簡(jiǎn)而言之:您的圖形用戶(hù)界面可能會(huì )占用大量?jì)却?您需要更加聰明,為實(shí)際應用程序留出足夠的空間。例如,節省圖形內存的一個(gè)快速方法是仔細檢查是否可以用矢量等價(jià)物替換某些光柵圖形(例如圖標):當然,直接在屏幕上繪制一個(gè)簡(jiǎn)單的32x32px紅方塊需要更少的代碼和RAM,而不是將其存儲為內存中的位圖。
資源管理
正確管理組成GUI項目的各種資源可能很棘手。更具體地說(shuō),您的GUI實(shí)體模型都可能由各種圖像文件、圖標、字體等組成。但是,在嵌入式開(kāi)發(fā)環(huán)境中,您通常不能期望能夠在代碼中直接操作漂亮的透明PNG文件或TrueType字體!首先需要將其轉換為允許在嵌入代碼中操作的格式。
事件處理和性能
首先,C語(yǔ)言仍然是*常用的嵌入式編程語(yǔ)言,它并不完全是面向對象的。因此,即使完全有可能以上面所示的高級API為目標,也很有可能在向某個(gè)UI元素添加/更新事件處理程序時(shí)使用容易出錯的函數指針。
假設您確實(shí)找到了一種優(yōu)雅的方式將事件處理程序與UI的各個(gè)部分關(guān)聯(lián)起來(lái),那么您仍然需要實(shí)現某種類(lèi)型的事件循環(huán)。事實(shí)上,您必須定期處理系統中發(fā)生的事件("按下按鈕A"等),并將它們發(fā)送給適當的事件處理程序。嵌入式編程中的一種常見(jiàn)模式是通過(guò)所謂的超級循環(huán)來(lái)實(shí)現:程序運行無(wú)限循環(huán),無(wú)限次地調用系統需要執行的每個(gè)任務(wù)。
這種方法的一個(gè)好處是,執行流保持了相當的可讀性和直觀(guān)性,并且還避免了復雜的多線(xiàn)程或中斷處理可能導致的一些潛在問(wèn)題。但是,任何運行時(shí)間過(guò)長(cháng)(或崩潰!)的事件處理程序都會(huì )影響主應用程序的性能和穩定性。
隨著(zhù)FreeRTOS或Azure RTOS ThreadX等嵌入式開(kāi)發(fā)的實(shí)時(shí)操作系統越來(lái)越流行,一種更現代的方法是讓UI事件循環(huán)在專(zhuān)用的后臺任務(wù)中運行。因此,操作系統可以確保此任務(wù)(優(yōu)先級較低)不會(huì )影響主應用程序的性能。
嵌入式GUI并不總是需要像fast和responsive那樣具有良好的性能。然而,盡可能高效地使用嵌入式資源被認為是一種良好的實(shí)踐。確保您的GUI和應用程序代碼的性能盡可能合理,這可能會(huì )為您節省大量資金,因為這意味著(zhù)您可以堅持使用盡可能*小的MCU來(lái)完成任務(wù)。