在一個初學者從入門走向精通的途中,像這種 發現問題 → 投入思考 → 提出方案 的學習模式是非常有效。
1
遇到的問題
通過這一段時間的編碼實踐,積累了一些編碼經驗,但也體會到了之前的代碼結構的缺陷:
(1)開發效率低:每次使用片內的某一資源(例如定時器等),筆者都要去查詢技術手冊,比較eggache~
(2)代碼重複較多:每個實驗源碼中,諸如 xtal_init ,led_init 等初始化函數每次都要編寫
(3)不易修改:代碼中的商務邏輯與SFR的操作混在一起,可讀性較差,修改起來也費力
2
由網站分層引起的思考
筆者在學習嵌入式編程之前,曾有過 ASP.NET 網站開發經驗,對其分層理論也有所實踐,下面簡單提一下:
一般的有一定複雜度的網站可分為以下三層:
(1)資料接入層(DAL):負責與資料庫的互動,供商務邏輯層調用
(2)商務邏輯層(BLL):調用資料接入層以擷取資料,並為具體的業務需求提供支援
(3)使用者介面層(UIL):負責呈現最終的使用者介面
相信很多朋友都對此非常熟悉,在此不再贅述。總之,分層以後,大大提高了代碼的複用性與擴充性。
那麼在嵌入式開發中,能否也利用分層的思想,來提高開發效率,增強其可維護性與可擴充性呢。下面,是一些筆者思考後的淺見。
3
嵌入式項目也來個分層
當然不能照搬ASP.NET 的具體分層思想,具體問題得具體分析嘛~
首先,嵌入式開發的核心就是晶片,它提供固定的片內資源共開發人員使用。而且它具有一個很重要的特點就是,不隨項目的需求變動而變動。所以應將其作為最底層,為上層提供基礎支援。我們將其命名為 硬體抽象層(Hardware Abstract Layer)。
晶片有了當然還不夠,通常我們會在片外擴充一些功能模組來滿足具體的項目需求,例如:感應器、鍵盤、LCD屏等。這一層的特點是,隨項目的變動而以模組為單位動態增減。這一層的運作需要晶片內部資源的支援,所以應處於硬體抽象層之上,並為上層調用。我們將其命名為 功能模組層(Functional Module Layer)。
OK,現在原材料都準備齊了:晶片+擴充模組,接下來就要開始真正的加工了:我們需要靈活調用之前兩層所提供的介面,實現具體的項目需求。我們將其命名為 應用程式層(Application Layer)。
圖文:
1.硬體抽象層(HAL)
實現對片內資源 (如定時器、ADC、中斷、I/O等) 的通用配置,隱藏具體的SFR操作細節,為上層提供簡單清晰的調用介面。
2.功能模組層(FML)
通過調用 HAL,實現項目中所涉及到的各片外功能模組,隱藏具體的模組操作細節,並為上層提供簡單清晰的調用介面。
3.應用程式層(APL)
通過調用 HAL 與 FML,實現最終的應用功能。
4
小試牛刀
OK,我們舉一個具體的例子,來說明分層思想的運用。
之前,筆者需要完成一個略帶綜合性的小實驗“溫度監測系統”,需求分析大概如下:
• CC2430節點實現對溫度的定時採集,並可通過LED燈指示其採樣頻率
• 節點將資料傳送至PC端
• 節點可以接收來自PC的控制指令,以調整採樣速率和電源模式
• 具備停機自動複位能力
• 可進入睡眠狀態,並可由按鍵喚醒
從上面的需求中我們可以看出,本實驗的核心晶片為CC2430,需要的片外擴充模組為LED燈與按鍵,預期要達到具體項目需求即以上5點。
接下來,我們利用上面提到的分層理論小試牛刀,對“溫度監測系統”這一實驗的代碼結構進行規劃:
應用程式層(APL)
[main.c] 引用 hal.h、ioCC2430.h 與 module.h,實現溫度採集、與PC互連信、停機複位等具體的應用需求
功能模組層(FML)
[module.h] 定義了一系列片外功能模組(LED、按鍵),以及一系列的相關函數的聲明
[module.c] 引用 hal.h,實現各片外模組(LED、按鍵)的功能
硬體抽象層(HAL)
[ioCC2430.h](系統內建):定義了CC2430的所有SFR 、中斷向量
[hal.h] 包括常用類型定義、常用賦值宏、以及CC2430片上資源的配置(I/O、串口通訊、ADC、定時器、電源管理等)
(註:由於本實驗所涉及的片外模組——LED與按鍵——的使用極其簡單,所以筆者將其合并入了單個源檔案。若遇到較複雜的模組,可以單獨建立 .h 與 .c 檔案來實現,如LCD.h、LCD.c)
經此設計,其優點逐漸浮出水面:
• 高效的開發速率:編完 HAL 層中的 hal.h 之後,我們就可以很方便地調用,而不必反覆地去查詢SFR的具體設定細則
• 快速擴充:若需要加強系統功能,只需在 FML 層添加相應功能模組(即 .c 檔案),並在 main.c 中調用即可
• 較高的代碼重用性:HAL 層所提供的SFR操作可供通用,而且該層幾乎不用修改就可直接用於新的CC2430項目中
• 較好的可維護性:項目代碼結構清晰,HAL 與 FML 幾乎不需要修改,只需修改 APL 即可
5
結論
可能對於嵌入式編程高手來說,上述理論可能完全算不得什麼,甚至還存在著很大的錯誤。不過在一個初學者從入門走向精通的途中,像這種 發現問題 → 投入思考 → 提出方案 的學習模式,我相信是值得而且很有必要的。就像很多人說的那樣:過程比結論更重要。
1.2018年第5期《單片機與嵌入式系統應用》電子刊新鮮出爐。
2.為什麼在單片機上的程式不怎麼使用malloc,而PC上經常使用?
3.晶片春秋·ARM傳
4.4月份程式設計語言流行度和招聘趨勢
5.程式員渴望的“無代碼世界”要來了。
6.為啥晶片那麼難搞。
免責聲明:本文系網路轉載,著作權歸原作者所有。如涉及作品著作權問題,請與我們聯絡,我們將根據您提供的著作權證明材料確認著作權並支付稿酬或者刪除內容。