嵌入式架構(gòu)到底有多重要奔缠?看完驚呆了

嵌入式架構(gòu)有多重要?

要做到嵌入式應(yīng)用的代碼邏輯清晰骄崩,

且避免重復(fù)的造輪子,

沒(méi)有好的應(yīng)用架構(gòu)怎么行?

http://www.makeru.com.cn/live/1392_401.html?s=144282

如果沒(méi)有好的架構(gòu)薄辅,

移植將會(huì)是一件很痛苦的事情要拂。

如果沒(méi)有好的架構(gòu),

復(fù)用是最大的難題站楚,

沒(méi)法更大限度的復(fù)用原有的代碼脱惰。

如果沒(méi)有好的架構(gòu),

一旦驅(qū)動(dòng)改了窿春,

所有的地方都要改拉一,

費(fèi)時(shí)費(fèi)力且很容易出錯(cuò)。

如果沒(méi)有好的架構(gòu)旧乞,

應(yīng)用層中穿插著硬件驅(qū)動(dòng)層的代碼蔚润,

看著會(huì)是一片混亂,

邏輯不清尺栖,

代碼維護(hù)起來(lái)會(huì)很困難嫡纠。

接下來(lái)嵌入式ARM便和大家分享一下,

嵌入式架構(gòu)那些事兒……

01

嵌入式系統(tǒng)的基本架構(gòu)

嵌入式系統(tǒng)一般由軟件和硬件兩個(gè)部分組成延赌,基中嵌入式處理器除盏、存儲(chǔ)器和外部設(shè)備構(gòu)成整個(gè)系統(tǒng)的硬件基礎(chǔ)。嵌入式系統(tǒng)的軟件部分可以分為三個(gè)層次挫以,分別是系統(tǒng)軟件者蠕、支撐軟件和應(yīng)用軟件,其中系統(tǒng)軟件和支撐軟件是基礎(chǔ)屡贺,應(yīng)用軟件是最能體現(xiàn)整個(gè)嵌入式系統(tǒng)的特點(diǎn)和功能部分蠢棱。

硬件架構(gòu)

嵌入式系統(tǒng)的核心部件是各種類型的嵌入式處理器

(1)嵌入式微處理器:在功能上跟普通微處理器基本一致,但是它具有體積小甩栈、功耗低泻仙、成本低及可靠性高的優(yōu)點(diǎn)。

(2)嵌入式微控制器:雙稱單片機(jī)量没,一般以某一種微處理器內(nèi)核為核心玉转,整個(gè)計(jì)算機(jī)系統(tǒng)都集成到一塊芯片中,與嵌入式微處理器相比殴蹄,最大特點(diǎn)是單片化究抓。

(3)嵌入式數(shù)字信號(hào)處理器:一種專門用于信號(hào)處理的處理器猾担,DSP(Digital Signal Processor)是芯片內(nèi)部采用程序和數(shù)據(jù)分開(kāi)的結(jié)構(gòu),具有專門的硬件乘法器刺下,廣泛采用流水線操作绑嘹,提供特殊的DSP指令。

(4)嵌入式片上系統(tǒng):一種在一塊芯片上集成很多功能模塊的復(fù)雜系統(tǒng)橘茉,在大量生產(chǎn)時(shí)工腋,生產(chǎn)成本也遠(yuǎn)遠(yuǎn)低于單片部件組成的電路板系統(tǒng)。


軟件架構(gòu)


大多數(shù)人參與的是嵌入式軟件設(shè)計(jì)畅卓,更多的是接觸的是上層軟件系統(tǒng)部分擅腰,可以分為兩大類型嵌入式軟件應(yīng)用工程師以及嵌入式驅(qū)動(dòng)工程師。


前者主要負(fù)責(zé) linux APP 設(shè)計(jì)翁潘,負(fù)責(zé)應(yīng)用層業(yè)務(wù)開(kāi)發(fā)趁冈,主要具備如下幾個(gè)專業(yè)技能:

1.熟悉網(wǎng)絡(luò)編程、TCP/IP協(xié)議拜马、IIC渗勘、SPI協(xié)議

2.熟悉多線程管理、進(jìn)程間通信一膨、文件IO操作

3.了解基本的shell編程

4.熟悉數(shù)據(jù)庫(kù)操作

5.了解QT或者Android

后者負(fù)責(zé)驅(qū)動(dòng)開(kāi)發(fā)呀邢,更加涉及底層。

1.熟悉uboot和Linux內(nèi)核豹绪,完成Linux內(nèi)核裁剪定制以及系統(tǒng)的固件更新

2.熟悉Linux驅(qū)動(dòng)模型

3.熟悉ARM架構(gòu)

4.熟悉基本的電路原理

02

嵌入式程序設(shè)計(jì)思路

現(xiàn)在的小朋友都愛(ài)玩搭積木的游戲价淌,一個(gè)模塊一個(gè)模塊的拼裝起來(lái),快速組成各種不同的模型÷鹘颍現(xiàn)在的產(chǎn)品設(shè)計(jì)也很少?gòu)牧汩_(kāi)始蝉衣。大都復(fù)用現(xiàn)有成熟的模塊,專注于某個(gè)擅長(zhǎng)領(lǐng)域巷蚪。

我的嵌入式應(yīng)用架構(gòu)思路來(lái)源與此病毡,即功能模塊設(shè)計(jì)與分層。

把API分為驅(qū)動(dòng)層和應(yīng)用層API屁柏,而不是所有程序都調(diào)用驅(qū)動(dòng)層API啦膜。(整個(gè)應(yīng)用中都調(diào)用驅(qū)動(dòng)層API會(huì)導(dǎo)致應(yīng)用中驅(qū)動(dòng)調(diào)用隨處可見(jiàn),無(wú)法移植和最大限度的復(fù)用)

先把一個(gè)應(yīng)用進(jìn)行功能模塊劃分淌喻,并對(duì)整體結(jié)構(gòu)進(jìn)行分層僧家,然后設(shè)計(jì)出功能獨(dú)立的各個(gè)模塊(如算法模塊,文件庫(kù)模塊裸删,通信庫(kù)模塊)八拱,在模塊之上開(kāi)放公共接口。

驅(qū)動(dòng)層提供出公共接口供上層調(diào)用。各個(gè)功能模塊可以獨(dú)立編譯(如算法模塊純ANSI C肌稻,可在任意平臺(tái)復(fù)用)清蚀,或者調(diào)用驅(qū)動(dòng)層接口(文件庫(kù)模塊調(diào)用了驅(qū)動(dòng)讀寫Flash),總而言之爹谭,言而總之枷邪,封裝出各個(gè)功能獨(dú)立的可復(fù)用的功能模塊。

總體分:硬件驅(qū)動(dòng)層–>功能模塊層–>應(yīng)用接口層–>業(yè)務(wù)邏輯層–>應(yīng)用層

總體結(jié)構(gòu)示意框圖:


應(yīng)用層诺凡,為程序的總體的運(yùn)行框架齿风,組織調(diào)用業(yè)務(wù)邏輯“舐澹可以用某種嵌入式操作系統(tǒng)實(shí)現(xiàn)幾種任務(wù) 。如定時(shí)任務(wù)童本,卡處理任務(wù)真屯,菜單任務(wù),通信任務(wù)穷娱。

業(yè)務(wù)邏輯層绑蔫,如CPU卡處理,交通部卡處理泵额,銀聯(lián)卡處理配深,M1卡處理,通信記錄上傳嫁盲,黑名單下載篓叶,票價(jià)參數(shù)下載等。

應(yīng)用接口層羞秤,提供公共的api接口供應(yīng)用接口供上層調(diào)用缸托。這些接口也可由下層的功能模塊開(kāi)放出來(lái),應(yīng)用接口層負(fù)責(zé)匯總瘾蛋。

功能模塊層俐镐,可以封裝不同的功能模塊。如算法庫(kù)哺哼,文件庫(kù)佩抹,通信庫(kù),銀聯(lián)庫(kù)取董,向上提供應(yīng)用接口層的接口棍苹,向下調(diào)用驅(qū)動(dòng)接口。

硬件驅(qū)動(dòng)層甲葬,由各個(gè)驅(qū)動(dòng)模塊組成廊勃,向上提供統(tǒng)一的接口。

遵循一些約定:

1.每個(gè)模塊提供出的接口要統(tǒng)一,后續(xù)只能增坡垫,不能改原來(lái)的接口梭灿。2.模塊與模塊之間相互獨(dú)立,互不影響冰悠,不能相互調(diào)用堡妒,只能調(diào)用它下層的接口。3.由模塊構(gòu)成層溉卓,層與層之間不能跨級(jí)調(diào)用皮迟。如在應(yīng)用層中不能看到直接調(diào)用驅(qū)動(dòng)層的代碼。4.模塊中又可以繼續(xù)分層桑寨,如接口層伏尼,驅(qū)動(dòng)層,硬件層尉尾。

如果驅(qū)動(dòng)變動(dòng)了爆阶,或者換不同平臺(tái),只需更改驅(qū)動(dòng)層沙咏,應(yīng)用層不受影響辨图。

如果功能模塊變動(dòng)了,只需升級(jí)功能功能模塊肢藐,其他的模塊不受影響故河,應(yīng)用層也不受影響。

按照這種邏輯設(shè)計(jì)好之后吆豹,主要的工作就是在業(yè)務(wù)邏輯層鱼的。應(yīng)用層則為程序的總體流程和框架,主要調(diào)用業(yè)務(wù)邏輯層實(shí)現(xiàn)不同的功能痘煤。

我們現(xiàn)在的代碼結(jié)構(gòu)鸳吸,基本是按這個(gè)思路來(lái)的。

硬件驅(qū)動(dòng)層–>功能模塊層–>應(yīng)用接口層–>業(yè)務(wù)邏輯層–>應(yīng)用層速勇。

看看以下兩種風(fēng)格的代碼晌砾,你更喜歡哪個(gè)。


另一種風(fēng)格:


同樣是保存參數(shù)烦磁,非要拆成 AlgCRC16 养匈,WritePraFlash( (unsigned char *)&NetPra , NETPRA_ADDR , sizeof(_NetPra) )兩步嗎?

還有AH_Para_Verify這個(gè)都伪,在應(yīng)用層中真是多余啊呕乎,檢測(cè)失敗又從Flash讀取。關(guān)于參數(shù)陨晶,一開(kāi)機(jī)就應(yīng)該檢測(cè)合法性了猬仁。


既然都是要保存參數(shù)帝璧,就應(yīng)該做個(gè)封裝,如上圖所示湿刽,把系統(tǒng)用到的不同參數(shù)做個(gè)規(guī)劃的烁。應(yīng)用層調(diào)用APP_Open_UseFile 或者APP_Read_UseFile,而不是直接的去讀寫Flash。

來(lái)看看赫赫有名的谷歌的android架構(gòu)诈闺,雖然很復(fù)雜渴庆,但從框圖上看,也像是搭積木雅镊,各個(gè)功能模塊獨(dú)立襟雷,層次分明。最低層建立在linux Kernel基礎(chǔ)上仁烹,然后是各個(gè)組件庫(kù)libraries耸弄,再往上是應(yīng)用框架和應(yīng)用。

以NC_FileLib,文件庫(kù)模塊為例卓缰,如果要用在其他平臺(tái)叙赚,如EH0918手持機(jī)設(shè)備,只需要移植幾個(gè)硬件層接口即可僚饭。

03

一個(gè)引以為戒的實(shí)例

一、錯(cuò)誤的示范

近公司新招了一個(gè)做嵌入式軟件開(kāi)發(fā)的同事胧砰,該同事是從上海的某一個(gè)上市公司出來(lái)的鳍鸵,因?yàn)槲覀冞@邊人手不夠,因此把他安排了去負(fù)責(zé)一個(gè)新產(chǎn)品的研發(fā)尉间,前期讓他負(fù)責(zé)加速度計(jì)偿乖、NB-IOT、舵機(jī)哲嘲、外置Flash的功能測(cè)試贪薪,測(cè)試完成之后,準(zhǔn)備讓他做一個(gè)該產(chǎn)品的概要設(shè)計(jì)眠副。然后他花了2個(gè)星期的時(shí)間画切,給我們寫出來(lái)一個(gè)概要設(shè)計(jì),說(shuō)實(shí)話囱怕,我看到這個(gè)概要設(shè)計(jì)霍弹,我就覺(jué)得是剛畢業(yè)的大學(xué)生寫的。

版本一的架構(gòu)設(shè)計(jì)

2.1系統(tǒng)體系結(jié)構(gòu)

系統(tǒng)分為兩層:硬件驅(qū)動(dòng)層娃弓、應(yīng)用層典格。

2.1.1硬件驅(qū)動(dòng)層

硬件驅(qū)動(dòng)層包含板載硬件資源正常運(yùn)行所需的所有驅(qū)動(dòng)程序。

1)MCU初始化

2)I2C數(shù)據(jù)存取

3)SPI數(shù)據(jù)讀取

4)加速度計(jì)初始化

5)藍(lán)牙模塊啟動(dòng)

6)BC95模塊啟動(dòng)

7)485通訊模塊啟動(dòng)

2.2.2應(yīng)用層

1)Mcu運(yùn)行模式切換

2)震動(dòng)及傾斜

3)數(shù)據(jù)解析

4)開(kāi)/關(guān)鎖

5)數(shù)據(jù)發(fā)送

6)歷史數(shù)據(jù)保存

看到版本一的架構(gòu)設(shè)計(jì)之后台丛,說(shuō)實(shí)話耍缴,我還是第一次見(jiàn)到這樣來(lái)寫架構(gòu)設(shè)計(jì)的,居然是以序號(hào)來(lái)寫的,這個(gè)讓別人讀起來(lái)防嗡,特別的別扭变汪。

版本二的架構(gòu)設(shè)計(jì)


看到版本二的架構(gòu)設(shè)計(jì)之后,雖然頗感欣慰本鸣,但是想到達(dá)到我們所要求的疫衩,還要很大的一段距離,該架構(gòu)設(shè)計(jì)荣德,主要有以下幾點(diǎn)問(wèn)題:

1.對(duì)架構(gòu)的理解還不是很清晰闷煤,既然是做架構(gòu)設(shè)計(jì),那就應(yīng)該從整體來(lái)看涮瞻,而不是僅僅只是局限于一個(gè)模塊鲤拿,或者功能里面。

2.還是每個(gè)層次的理解也還不是很清晰署咽,比如講MCU的初始化近顷,歸于硬件驅(qū)動(dòng)層里面。MCU的初始化宁否,嚴(yán)格意義上來(lái)說(shuō)窒升,是屬于流程的一部分了,而不是驅(qū)動(dòng)慕匠。比如電腦的開(kāi)啟啟動(dòng)饱须,把這個(gè)歸于硬件的驅(qū)動(dòng)里面,肯定是屬于牛頭不對(duì)馬嘴的台谊。

3.還有就是各個(gè)模塊的啟動(dòng)蓉媳,也是不能屬于硬件驅(qū)動(dòng)層的,也都是業(yè)務(wù)流程的一部分了锅铅,都不應(yīng)該屬于驅(qū)動(dòng)層的一部分酪呻。

4.還有就是總線數(shù)據(jù)的讀寫,雖然驅(qū)動(dòng)的作用也就是讀寫盐须,但是數(shù)據(jù)總線的讀寫不能寫成硬件驅(qū)動(dòng)玩荠。

5.應(yīng)用層的系統(tǒng)參數(shù)初始化,也還是屬于流程贼邓。

6.數(shù)據(jù)的解析和數(shù)據(jù)的發(fā)生姨蟋,都是屬于通信功能里面的,不應(yīng)該單獨(dú)獨(dú)立出來(lái)立帖,屬于單個(gè)的應(yīng)用眼溶。

二、更改版基本框架圖

(1)架構(gòu)設(shè)計(jì)的目的

1.應(yīng)用的代碼邏輯清晰晓勇,且避免重復(fù)造輪子堂飞。

2.如果沒(méi)有好的架構(gòu)灌旧,移植將會(huì)是一件很痛苦的事情,因此一個(gè)好的架構(gòu)設(shè)計(jì)绰筛,方便軟件的移植枢泰。

3.最大限度地復(fù)用。

4.高內(nèi)聚低耦合铝噩。

(2)設(shè)計(jì)思路

如何把硬件的驅(qū)動(dòng)和一個(gè)功能封裝成一個(gè)個(gè)的模塊衡蚂,然后可以像小朋友搭積木一個(gè),一個(gè)個(gè)模塊可以快速的拼接起來(lái)骏庸,組成一個(gè)個(gè)不同的模型毛甲。

我們的嵌入式架構(gòu)思路也是來(lái)源于此,即功能模塊化設(shè)計(jì)具被、分層設(shè)計(jì)玻募。

這個(gè)設(shè)計(jì)和WEB開(kāi)發(fā)的MVC模式類似,都是注重分層設(shè)計(jì)一姿。

模塊化設(shè)計(jì):將收集到的需求七咧,進(jìn)行歸類,總結(jié)和分析叮叹,將這些需求概括為一個(gè)個(gè)單獨(dú)的功能艾栋,每一個(gè)功能,做成一個(gè)單獨(dú)的功能模塊蛉顽。

分層設(shè)計(jì)一句話不好直接表達(dá)蝗砾,其主要體現(xiàn)在一下幾方面:

1.功能模塊對(duì)外調(diào)用的模塊封裝成一個(gè)個(gè)API,將底層驅(qū)動(dòng)做個(gè)API以供功能模塊調(diào)用蜂林。(各個(gè)功能模塊可以獨(dú)立編譯(如通信模塊純ANSI C,可在任意平臺(tái)復(fù)用)拇泣,或者調(diào)用驅(qū)動(dòng)層接口(日志庫(kù)模塊調(diào)用了驅(qū)動(dòng)讀寫Flash)噪叙,總而言之,言而總之霉翔,封裝出各個(gè)功能獨(dú)立的可復(fù)用的功能模塊睁蕾。)

2.API分為驅(qū)動(dòng)層API和應(yīng)用層API,而不是所有程序都調(diào)用驅(qū)動(dòng)層API债朵。(整個(gè)應(yīng)用中都調(diào)用驅(qū)動(dòng)層API會(huì)導(dǎo)致應(yīng)用中驅(qū)動(dòng)調(diào)用隨處可見(jiàn)子眶,無(wú)法移植和最大限度的復(fù)用)

總體分 硬件驅(qū)動(dòng)層–>功能模塊層–>業(yè)務(wù)邏輯層–>應(yīng)用層

總體結(jié)構(gòu)示意框圖:


說(shuō)明:

1.層與層之間不能跨層調(diào)用。

2.模塊與模塊各自獨(dú)立序芦,無(wú)依賴關(guān)系臭杰。

3.模塊提供統(tǒng)一的接口供上層調(diào)用,模塊的內(nèi)外接口分明谚中。

4.模塊的功能只能增渴杆,不能改寥枝。

5.各個(gè)功能模塊層也還可以進(jìn)行繼續(xù)分層,比如接口層磁奖、驅(qū)動(dòng)層囊拜、硬件層。

(3)模塊層次說(shuō)明

硬件驅(qū)動(dòng)層

硬件驅(qū)動(dòng)層包含板載硬件資源正常運(yùn)行所需的所有驅(qū)動(dòng)程序并提供API給功能模塊調(diào)用比搭。

功能模塊層

功能模塊層包括實(shí)現(xiàn)具體功能的函數(shù)冠跷,通過(guò)調(diào)用驅(qū)動(dòng)層API實(shí)現(xiàn)相應(yīng)功能,同時(shí)提供可調(diào)用的API給業(yè)務(wù)邏輯層身诺。

業(yè)務(wù)邏輯層

業(yè)務(wù)邏輯層包括產(chǎn)品整體功能的各個(gè)業(yè)務(wù)流程蜜托,通過(guò)調(diào)用功能模塊層的API實(shí)現(xiàn)。

應(yīng)用層

應(yīng)用層將各個(gè)業(yè)務(wù)邏輯進(jìn)行整合調(diào)用戚长,完成整個(gè)產(chǎn)品的功能盗冷。

(4)優(yōu)勢(shì)

如果驅(qū)動(dòng)變動(dòng)了,或者換不同平臺(tái)同廉,只需更改驅(qū)動(dòng)層仪糖,應(yīng)用層不受影響。

如果功能模塊變動(dòng)了迫肖,只需升級(jí)相應(yīng)的功能模塊锅劝,其他的模塊不受影響,應(yīng)用層也不受影響蟆湖。

按照這種邏輯設(shè)計(jì)好之后故爵,主要的工作就是在業(yè)務(wù)邏輯層。應(yīng)用層則為程序的總體流程和框架隅津,主要調(diào)用業(yè)務(wù)邏輯層實(shí)現(xiàn)不同的功能诬垂。

04

給嵌入式代碼也來(lái)個(gè)分層

一、遇到的問(wèn)題

代碼結(jié)構(gòu)也會(huì)有缺陷:

(1)開(kāi)發(fā)效率低:每次使用片內(nèi)的某一資源(例如定時(shí)器等)伦仍,筆者都要去查詢CC2430中文手冊(cè)结窘,比較eggache~(2)代碼重復(fù)較多:每個(gè)實(shí)驗(yàn)源碼中,諸如 xtal_init 充蓝,led_init 等初始化函數(shù)每次都要編寫(3)不易修改:代碼中的業(yè)務(wù)邏輯與SFR的操作混在一起隧枫,可讀性較差,修改起來(lái)也費(fèi)力

正是由于以上問(wèn)題谓苟,筆者決定暫停了該系列博文的續(xù)寫官脓,抽出時(shí)間來(lái)思考一下解決辦法。

二涝焙、由網(wǎng)站分層引起的思考

筆者在學(xué)習(xí)嵌入式編程之前卑笨,曾有過(guò) 網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn),對(duì)其分層理論也有所實(shí)踐仑撞,下面簡(jiǎn)單提一下:

一般的有一定復(fù)雜度的網(wǎng)站可分為以下三層:

(1)數(shù)據(jù)接入層(DAL):負(fù)責(zé)與數(shù)據(jù)庫(kù)的交互湾趾,供業(yè)務(wù)邏輯層調(diào)用(2)業(yè)務(wù)邏輯層(BLL):調(diào)用數(shù)據(jù)接入層以獲取數(shù)據(jù)芭商,并為具體的業(yè)務(wù)需求提供支持(3)用戶界面層(UIL):負(fù)責(zé)呈現(xiàn)最終的用戶界面

總之,分層以后搀缠,大大提高了代碼的復(fù)用性與擴(kuò)展性铛楣。

那么在嵌入式開(kāi)發(fā)中,能否也利用分層的思想艺普,來(lái)提高開(kāi)發(fā)效率簸州,增強(qiáng)其可維護(hù)性與可擴(kuò)展性呢?下面歧譬,是一些筆者思考后的淺見(jiàn)岸浑。

三、嵌入式項(xiàng)目也來(lái)分個(gè)層

當(dāng)然不能照搬 的具體分層思想瑰步,具體問(wèn)題得具體分析嘛~

首先矢洲,嵌入式開(kāi)發(fā)的核心就是芯片,它提供固定的片內(nèi)資源共開(kāi)發(fā)者使用缩焦。而且它具有一個(gè)很重要的特點(diǎn)就是读虏,不隨項(xiàng)目的需求變動(dòng)而變動(dòng)。所以應(yīng)將其作為最底層袁滥,為上層提供基礎(chǔ)支持盖桥。我們將其命名為 硬件抽象層(Hardware Abstract Layer)。

芯片有了當(dāng)然還不夠题翻,通常我們會(huì)在片外擴(kuò)展一些功能模塊來(lái)滿足具體的項(xiàng)目需求揩徊,例如:傳感器、鍵盤嵌赠、LCD屏等塑荒。這一層的特點(diǎn)是,隨項(xiàng)目的變動(dòng)而以模塊為單位動(dòng)態(tài)增減姜挺。這一層的運(yùn)作需要芯片內(nèi)部資源的支持齿税,所以應(yīng)處于硬件抽象層之上,并為上層調(diào)用初家。我們將其命名為 功能模塊層(Functional Module Layer)偎窘。

OK乌助,現(xiàn)在原材料都準(zhǔn)備齊了:芯片+擴(kuò)展模塊溜在,接下來(lái)就要開(kāi)始真正的加工了:我們需要靈活調(diào)用之前兩層所提供的接口,實(shí)現(xiàn)具體的項(xiàng)目需求他托。我們將其命名為應(yīng)用程序?qū)樱ˋpplication Layer)掖肋。

圖文:


(1)硬件抽象層(HAL)

實(shí)現(xiàn)對(duì)片內(nèi)資源 (如定時(shí)器、ADC赏参、中斷志笼、I/O等) 的通用配置沿盅,隱藏具體的SFR操作細(xì)節(jié),為上層提供簡(jiǎn)單清晰的調(diào)用接口纫溃。

嵌入式開(kāi)發(fā)的核心就是芯片腰涧,它提供固定的片內(nèi)資源(常用的有I/O,ISR紊浩,TIMER等窖铡,稍微好點(diǎn)的還有ADC,SPI等硬件資源坊谁,不需要芯片外圍ADC采集芯片或模擬SPI)共開(kāi)發(fā)者使用费彼。而且它具有一個(gè)很重要的特點(diǎn)就是,不隨項(xiàng)目的新增需求變動(dòng)而變動(dòng)口芍。所以應(yīng)將其作為最底層箍铲,為上層提供基礎(chǔ)支持。

(2)硬件驅(qū)動(dòng)層(HDL)

嵌入式開(kāi)發(fā)基本都會(huì)使用片外資源鬓椭,如AT24C02颠猴,W25Q128等常見(jiàn)的外圍EEPROM芯片,需要SPI通信(硬件SPI或I/O模擬的SPI)發(fā)送相應(yīng)指令驅(qū)動(dòng)該芯片膘融,實(shí)現(xiàn)該芯片能正常工作芙粱。因此驅(qū)動(dòng)這部分的API函數(shù)實(shí)現(xiàn)程序即為硬件驅(qū)動(dòng)層。即使換了MCU氧映,也只需將調(diào)用過(guò)硬件抽象層的API函數(shù)替換即可春畔。

(3)功能模塊層(FML)

通過(guò)調(diào)用 HAL,實(shí)現(xiàn)項(xiàng)目中所涉及到的各片外功能模塊岛都,隱藏具體的模塊操作細(xì)節(jié)律姨,并為上層提供簡(jiǎn)單清晰的調(diào)用接口。

硬件抽象層和驅(qū)動(dòng)層主要就是為功能模塊層提供的臼疫,實(shí)現(xiàn)該項(xiàng)目需要的功能择份,比如KEY、LED和EEPROM等功能烫堤,其中LEY荣赶、LED基本調(diào)用硬件抽象層的API函數(shù)(更復(fù)雜的可能通過(guò)片外芯片獲取/控制等,因此可能也需要使用硬件驅(qū)動(dòng)層)鸽斟,EEPROM調(diào)用硬件驅(qū)動(dòng)層的API函數(shù)拔创,即使EEPROM芯片更換(AT24C02或W25Q128等),也不影響EEPROM之前編寫含的功能代碼程序(前提是AT24C02富蓄,W25Q128提供的API函數(shù)提供的是統(tǒng)一標(biāo)準(zhǔn))剩燥。

(4)應(yīng)用程序?qū)樱ˋPL)

通過(guò)調(diào)用 HAL 與 FML,實(shí)現(xiàn)最終的應(yīng)用功能立倍。

負(fù)責(zé)的就是功能模塊的使用和之間的邏輯關(guān)系處理等等灭红,比如用戶交互界面應(yīng)用程序可能需要KEY侣滩、LED、LCD等变擒。

四君珠、硬件抽象層和硬件驅(qū)動(dòng)層的主要區(qū)別

硬件抽象層使用的芯片內(nèi)本身的資源(芯片手冊(cè)都有介紹),而硬件驅(qū)動(dòng)層使用的是芯片本身不存在的資源娇斑,而且需要編寫相應(yīng)代碼才能實(shí)現(xiàn)的資源葛躏。

比如正點(diǎn)原子STM32中CAN使用的TJA1050芯片,CAN屬于STM32的片內(nèi)資源悠菜,TJA1050屬于片外資源舰攒,但由于TJA1050不需要額外的代碼就能通過(guò)STM32中CAN本身提供API函數(shù)正常 工作;因此可以認(rèn)為TJA1050不屬于硬件驅(qū)動(dòng)層悔醋,而若使用TJA1041摩窃,則需要編寫額外代碼才能使正常工作才能使STM32中CAN本身提供API函數(shù)正常工作,因此可以將TJA1041歸為硬件驅(qū)動(dòng)層芬骄。

若不要分這么細(xì)猾愿,可以將硬件抽象層和硬件驅(qū)動(dòng)層統(tǒng)一歸為硬件抽象層。

五账阻、功能模塊層和硬件抽象層蒂秘、硬件驅(qū)動(dòng)層的主要區(qū)別

功能模塊層是按照項(xiàng)目需求提取出來(lái)的功能,需要硬件抽象層和硬件驅(qū)動(dòng)層的硬件支持才能實(shí)現(xiàn)淘太,功能模塊層根據(jù)項(xiàng)目的功能需求改變而改變姻僧,而硬件抽象層和硬件驅(qū)動(dòng)層則是項(xiàng)目需求書中的功耗等硬件相關(guān)的需求變動(dòng)而改變,當(dāng)然蒲牧,若子功能的增加而硬件不支持撇贺,則也需更換硬件驅(qū)動(dòng)。

比如項(xiàng)目中的數(shù)據(jù)儲(chǔ)存功能冰抢,硬件支持有AT24C02松嘶、W25Q128和芯片本身的FLASH,都可以支持?jǐn)?shù)據(jù)儲(chǔ)存功能挎扰,即使后期因?yàn)楣幕蚬?jié)約成本等問(wèn)題翠订,硬件的更換也不影響數(shù)據(jù)儲(chǔ)存功能的實(shí)現(xiàn)(前提規(guī)劃好標(biāo)準(zhǔn)規(guī)范的API函數(shù)定義)且避免了重寫該功能代碼所帶來(lái)的各種問(wèn)題,保證了該功能的穩(wěn)定性遵倦。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末目锭,一起剝皮案震驚了整個(gè)濱河市肆饶,隨后出現(xiàn)的幾起案子贾漏,更是在濱河造成了極大的恐慌岩睁,老刑警劉巖歧寺,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燥狰,死亡現(xiàn)場(chǎng)離奇詭異棘脐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)龙致,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蛀缝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人目代,你說(shuō)我怎么就攤上這事屈梁。” “怎么了榛了?”我有些...
    開(kāi)封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵在讶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我霜大,道長(zhǎng)构哺,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任战坤,我火速辦了婚禮曙强,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘途茫。我一直安慰自己碟嘴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布囊卜。 她就那樣靜靜地躺著娜扇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栅组。 梳的紋絲不亂的頭發(fā)上袱衷,一...
    開(kāi)封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音笑窜,去河邊找鬼致燥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛排截,可吹牛的內(nèi)容都是我干的嫌蚤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼断傲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼脱吱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起认罩,我...
    開(kāi)封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤箱蝠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體宦搬,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牙瓢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了间校。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矾克。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖憔足,靈堂內(nèi)的尸體忽然破棺而出胁附,到底是詐尸還是另有隱情,我是刑警寧澤滓彰,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布控妻,位于F島的核電站,受9級(jí)特大地震影響揭绑,放射性物質(zhì)發(fā)生泄漏饼暑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一洗做、第九天 我趴在偏房一處隱蔽的房頂上張望弓叛。 院中可真熱鬧,春花似錦诚纸、人聲如沸撰筷。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)毕籽。三九已至,卻和暖如春井辆,著一層夾襖步出監(jiān)牢的瞬間关筒,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工杯缺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒸播,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓萍肆,卻偏偏與公主長(zhǎng)得像袍榆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子塘揣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354