內(nèi)容整理自網(wǎng)絡,編輯:付斌
在一個初學者從入門走向精通的途中,像這種 發(fā)現(xiàn)問題 → 投入思考 → 提出方案 的學習模式是非常有效的。
一 、 遇到的問題
通過這一段時間的編碼實踐,積累了一些編碼經(jīng)驗,但也體會到了之前的代碼結構的缺陷:
(1)開發(fā)效率低:每次使用片內(nèi)的某一資源(例如定時器等),筆者都要去查詢技術手冊,比較eggache~
(2)代碼重復較多:每個實驗源碼中,諸如?xtal_init?,led_init?等初始化函數(shù)每次都要編寫
(3)不易修改:代碼中的業(yè)務邏輯與SFR的操作混在一起,可讀性較差,修改起來也費力
二? 、由網(wǎng)站分層引起的思考
在學習嵌入式編程之前,我曾有過 ASP.NET 網(wǎng)站開發(fā)經(jīng)驗,對其分層理論也有所實踐,下面簡單提一下:
一般的有一定復雜度的網(wǎng)站可分為以下三層:
(1)數(shù)據(jù)接入層(DAL):負責與數(shù)據(jù)庫的交互,供業(yè)務邏輯層調(diào)用
(2)業(yè)務邏輯層(BLL):調(diào)用數(shù)據(jù)接入層以獲取數(shù)據(jù),并為具體的業(yè)務需求提供支持
(3)用戶界面層(UIL):負責呈現(xiàn)最終的用戶界面
相信很大一部分朋友都對此非常熟悉,在此不再贅述。總之,分層以后,大大提高了代碼的復用性與擴展性。
那么在嵌入式開發(fā)中,能否也利用分層的思想,來提高開發(fā)效率,增強其可維護性與可擴展性呢?
?
三 、嵌入式項目也來個分層
當然不能照搬ASP.NET 的具體分層思想,具體問題得具體分析嘛。
首先,嵌入式開發(fā)的核心就是芯片,它提供固定的片內(nèi)資源共開發(fā)者使用。而且它具有一個很重要的特點就是,不隨項目的需求變動而變動。所以應將其作為最底層,為上層提供基礎支持。我們將其命名為?硬件抽象層(Hardware Abstract Layer)。
芯片有了當然還不夠,通常我們會在片外擴展一些功能模塊來滿足具體的項目需求,例如:傳感器、鍵盤、LCD屏等。這一層的特點是,隨項目的變動而以模塊為單位動態(tài)增減。這一層的運作需要芯片內(nèi)部資源的支持,所以應處于硬件抽象層之上,并為上層調(diào)用。我們將其命名為?功能模塊層(Functional Module Layer)。
OK,現(xiàn)在原材料都準備齊了:芯片+擴展模塊,接下來就要開始真正的加工了:我們需要靈活調(diào)用之前兩層所提供的接口,實現(xiàn)具體的項目需求。我們將其命名為?應用程序?qū)樱ˋpplication Layer)。
圖文:
?
(1)硬件抽象層(HAL)
實現(xiàn)對片內(nèi)資源 (如定時器、ADC、中斷、I/O等) 的通用配置,隱藏具體的SFR操作細節(jié),為上層提供簡單清晰的調(diào)用接口。
(2)功能模塊層(FML)
通過調(diào)用 HAL,實現(xiàn)項目中所涉及到的各片外功能模塊,隱藏具體的模塊操作細節(jié),并為上層提供簡單清晰的調(diào)用接口。
(3)應用程序?qū)樱ˋPL)
通過調(diào)用?HAL?與?FML,實現(xiàn)最終的應用功能。
四? 、小試牛刀
OK,我們舉一個具體的例子,來說明分層思想的運用。
之前,曾經(jīng)有一個需要完成一個略帶綜合性的小實驗“溫度監(jiān)測系統(tǒng)”的項目,需求分析大概如下:
??CC2430節(jié)點實現(xiàn)對溫度的定時采集,并可通過LED燈指示其采樣頻率
??節(jié)點將數(shù)據(jù)傳送至PC端
??節(jié)點可以接收來自PC的控制指令,以調(diào)整采樣速率和電源模式
??具備停機自動復位能力
? 可進入睡眠狀態(tài),并可由按鍵喚醒
從上面的需求中我們可以看出,本實驗的核心芯片為CC2430,需要的片外擴展模塊為LED燈與按鍵,預期要達到具體項目需求即以上五點。
接下來,我們利用上面提到的分層理論小試牛刀,對“溫度監(jiān)測系統(tǒng)”這一實驗的代碼結構進行規(guī)劃:
(1)應用程序?qū)樱ˋPL)
[main.c] 引用?hal.h、ioCC2430.h?與?module.h,實現(xiàn)溫度采集、與PC互通信、停機復位等具體的應用需求
(2)功能模塊層(FML)
[module.h] 定義了一系列片外功能模塊(LED、按鍵),以及一系列的相關函數(shù)的聲明
[module.c] 引用 hal.h,實現(xiàn)各片外模塊(LED、按鍵)的功能
(3)硬件抽象層(HAL)
[ioCC2430.h](系統(tǒng)自帶):定義了CC2430的所有SFR 、中斷向量
[hal.h] 包括常用類型定義、常用賦值宏、以及CC2430片上資源的配置(I/O、串口通訊、ADC、定時器、電源管理等)
(注:由于本實驗所涉及的片外模塊——LED與按鍵——的使用極其簡單,所以筆者將其合并入了單個源文件。若遇到較復雜的模塊,可以單獨新建 .h 與 .c 文件來實現(xiàn),如LCD.h、LCD.c)
經(jīng)此設計,其優(yōu)點逐漸浮出水面:
? 高效的開發(fā)速率:編完 HAL 層中的?hal.h?之后,我們就可以很方便地調(diào)用,而不必反復地去查詢SFR的具體設置細則
? 快速擴展:若需要加強系統(tǒng)功能,只需在 FML 層添加相應功能模塊(即 .c 文件),并在?main.c 中調(diào)用即可
? 較高的代碼重用性:HAL 層所提供的SFR操作可供通用,而且該層幾乎不用修改就可直接用于新的CC2430項目中?
? 較好的可維護性:項目代碼結構清晰,HAL 與 FML 幾乎不需要修改,只需修改 APL 即可
五 、結論
可能對于嵌入式編程高手來說,上述理論可能完全算不得什么,甚至還存在著很大的錯誤。不過在一個初學者從入門走向精通的途中,像這種?發(fā)現(xiàn)問題 →?投入思考 →?提出方案?的學習模式,我相信是值得而且很有必要的。就像很多人說的那樣:過程比結論更重要。