硬件抽象層對(duì)下必須檢驗(yàn)查看目前硬件配置的能力與限制劣砍,以及將來(lái)可能的擴(kuò)展性惧蛹,對(duì)上得傾聽(tīng)系統(tǒng)軟件得需求。簡(jiǎn)單得說(shuō),HAL就是我們系統(tǒng)的“硬件”赊淑,而“硬件”的功能就是它所提供的API爵政,即所有上層的程序完全不需要知道硬件與驅(qū)動(dòng)程序的細(xì)節(jié),只能通過(guò)HAL來(lái)操控硬件陶缺。按照這樣的邏輯,通常我們實(shí)現(xiàn)HAL的流程如下:
定義HAL的規(guī)模(Scope):根據(jù)需求分析上層的系統(tǒng)和應(yīng)用程序需要哪些硬件功能洁灵,這些需求就是HAL必須要包含的基本模塊饱岸,然后再根據(jù)硬件配置,分析是否仍有目前系統(tǒng)沒(méi)用到的硬件功能徽千,這些功能可能會(huì)在下一代產(chǎn)品中實(shí)現(xiàn)苫费,我們可以為其設(shè)計(jì)相應(yīng)的HAL模塊的API,但可以先不實(shí)現(xiàn)双抽;
-
定義HAL API:
系統(tǒng)工程師說(shuō)明系統(tǒng)需求百框,包含系統(tǒng)對(duì)硬件事件的處理方式。
固件工程師根據(jù)硬件功能牍汹,提供第一版的HAL API定義文件铐维;
系統(tǒng)工程師協(xié)同固件工程師逐一review HAL API。
在HAL API立項(xiàng)前慎菲,必須針對(duì)項(xiàng)目中的所有軟件工程師做詳細(xì)報(bào)告嫁蛇,收集建議,并做必要的修正露该。
由固件工程師實(shí)現(xiàn)所有的HAL的功能睬棚,并執(zhí)行每個(gè)模塊的單元測(cè)試;
固件工程師release第一版HAL庫(kù)解幼,由系統(tǒng)工程師負(fù)責(zé)整合測(cè)試抑党。
所以HAL不過(guò)是驅(qū)動(dòng)程序提供給上層應(yīng)用的API標(biāo)準(zhǔn)而已。
1撵摆、HAL基本設(shè)計(jì)原則
HAL設(shè)計(jì)文件是以驅(qū)動(dòng)來(lái)區(qū)分章節(jié)底靠,不同的驅(qū)動(dòng)由不同專長(zhǎng)的工程師負(fù)責(zé)設(shè)計(jì)與編寫(xiě)。因此設(shè)計(jì)文件的第一章是HAL基本設(shè)計(jì)原則台汇,第二章是共享數(shù)據(jù)結(jié)構(gòu)與常數(shù)定義苛骨。以下是設(shè)計(jì)原則:
往前兼容,新版的HAL的API可以變多苟呐,但不能減少痒芝;
HAL旨在對(duì)硬件做抽象化,不應(yīng)與任何系統(tǒng)有直接關(guān)系牵素。若OS對(duì)驅(qū)動(dòng)有特殊需求(Linux有制式的驅(qū)動(dòng)寫(xiě)法)严衬,應(yīng)由系統(tǒng)團(tuán)隊(duì)根據(jù)需求自行在HAL之上再往上包一層high level driver。
驅(qū)動(dòng)模塊化笆呆,盡量降低驅(qū)動(dòng)間的耦合度请琳。
-
每個(gè)驅(qū)動(dòng)分別設(shè)計(jì)粱挡,但章節(jié)內(nèi)的結(jié)構(gòu)必須保持一致,主要包含以下信息:
數(shù)據(jù)結(jié)構(gòu)
API
控制流程或狀態(tài)機(jī)
會(huì)產(chǎn)生的硬件事件俄精,以及事件傳遞流程
-
每個(gè)驅(qū)動(dòng)模塊應(yīng)該盡量包裝以下的API询筏,以保持所有驅(qū)動(dòng)模塊的API風(fēng)格一致:
Open():執(zhí)行該設(shè)備的初始化(包含硬件的初始化、取得驅(qū)動(dòng)所需的buffer竖慧、數(shù)據(jù)結(jié)構(gòu)或配置的設(shè)定等)
Enable():驅(qū)動(dòng)開(kāi)始運(yùn)行
Disable:驅(qū)動(dòng)暫停運(yùn)行
Close():關(guān)掉硬件設(shè)備嫌套,還回buffer,reset 驅(qū)動(dòng)的數(shù)據(jù)結(jié)構(gòu)或配置圾旨。
Set_Power_mode():設(shè)定該設(shè)備的power mode(full run踱讨、idle、sleep mode),即使該硬件不需要這種電壓管理砍的,也要設(shè)計(jì)出空的Set_Power_mode函數(shù)痹筛,以保持所有驅(qū)動(dòng)接口的一致性。
驅(qū)動(dòng)與電源管理的配合:驅(qū)動(dòng)僅提供電源管理的機(jī)制廓鞠,而電源管理的策略由系統(tǒng)的power manager 統(tǒng)一管控帚稠,即HAL中的每一個(gè)驅(qū)動(dòng)模塊都必須配合power manager 的需求,例如都必須實(shí)現(xiàn)Set_Power_mode() 這樣的API诫惭。
HAL的每個(gè)驅(qū)動(dòng)模塊都必須遵守共同的命名規(guī)則與API風(fēng)格字币。
統(tǒng)一定義HAL的系統(tǒng)配置:這些配置必須開(kāi)放給系統(tǒng)使用抛蚁,是的本項(xiàng)目不需要的驅(qū)動(dòng)模塊或功能不會(huì)被連接進(jìn)來(lái)。例如:
<pre mdtype="fences" cid="n249" lang="c" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> #include <hal.h>
ifdef HAL_WITH_GPS //HAL_WITH_GPS為HAL配置之一,定義在hal.h中
...
endif</pre>
2演侯、驅(qū)動(dòng)程序與系統(tǒng)的溝通機(jī)制
系統(tǒng)與HAL的溝通方式有3種:
HAL API:系統(tǒng)可以直接調(diào)用HAL開(kāi)放的API恢总。
-
ISR 與 硬件事件:當(dāng)硬件產(chǎn)生中斷時(shí)探膊,相應(yīng)的ISR會(huì)執(zhí)行颗圣;當(dāng)ISR處理完后,可將硬件事件抽象化篮撑,包裝成硬件事件减细,往上層系統(tǒng)傳遞,傳遞的方式有:
全局變量flag:當(dāng)上層程序發(fā)現(xiàn)flag的值變化了赢笨,即表示發(fā)生了某硬件事件未蝌。但這種方法的時(shí)效性差,且還要注意Critical section的保護(hù)茧妒;
在ISR內(nèi)調(diào)用系統(tǒng)功能萧吠,如send_message()、wakeup_task()等桐筏,這是普遍的做法纸型,但破壞了HAL必須與上層系統(tǒng)無(wú)關(guān)的規(guī)范。
好的做法是,HAL不決定傳遞硬件事件的機(jī)制狰腌,改為提供API除破,讓系統(tǒng)可“注冊(cè)”用以傳遞硬件事件的函數(shù)(回調(diào)函數(shù)callback function),ISR會(huì)在適當(dāng)時(shí)機(jī)調(diào)用這些函數(shù)琼腔,至于系統(tǒng)如何處理硬件事件瑰枫,ISR并不知道。
Callback:HAL 提供注冊(cè)callback function的API丹莲,并明確說(shuō)明調(diào)用此callback function的時(shí)機(jī)躁垛。系統(tǒng)只要傳入function pointer,HAL即會(huì)在上述時(shí)機(jī)調(diào)用這些callback function圾笨。例如當(dāng)HAL準(zhǔn)備關(guān)機(jī)時(shí),會(huì)去調(diào)用系統(tǒng)預(yù)線注冊(cè)的callback function逊谋,讓系統(tǒng)有機(jī)會(huì)做一些處理擂达。
3、驅(qū)動(dòng)接口
我們以HAL里重要的驅(qū)動(dòng)——Audio為例胶滋,看一下該驅(qū)動(dòng)的接口板鬓。按照設(shè)計(jì)文件風(fēng)格規(guī)范,必須先描述這個(gè)模塊中所有的API的關(guān)系:
獲取更多知識(shí)究恤,請(qǐng)點(diǎn)擊關(guān)注:
嵌入式Linux&ARM
CSDN博客
簡(jiǎn)書(shū)博客
知乎專欄