凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動
一、案例簡介
該程序是基于OpenHarmony標準系統(tǒng)編寫的基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動。
目前已在凌蒙派-RK3568開發(fā)板跑通。
詳細資料請參考官網(wǎng):https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony。
二、基礎(chǔ)知識
1、OpenHarmony HDF開發(fā)簡介
HDF(Hardware Driver Foundation)驅(qū)動框架,為驅(qū)動開發(fā)者提供驅(qū)動框架能力,包括驅(qū)動加載、驅(qū)動服務(wù)管理、驅(qū)動消息機制和配置管理。旨在構(gòu)建統(tǒng)一的驅(qū)動架構(gòu)平臺,為驅(qū)動開發(fā)者提供更精準、更高效的開發(fā)環(huán)境,力求做到一次開發(fā),多系統(tǒng)部署。
2、OpenHarmony HDF驅(qū)動開發(fā)
HDF(Hardware Driver Foundation)框架以組件化的驅(qū)動模型作為核心設(shè)計思路,為開發(fā)者提供更精細化的驅(qū)動管理,讓驅(qū)動開發(fā)和部署更加規(guī)范。HDF框架將一類設(shè)備驅(qū)動放在同一個Host(設(shè)備容器)里面,用于管理一組設(shè)備的啟動加載等過程。在劃分Host時,驅(qū)動程序是部署在一個Host還是部署在不同的Host,主要考慮驅(qū)動程序之間是否存在耦合性,如果兩個驅(qū)動程序之間存在依賴,可以考慮將這部分驅(qū)動程序部署在一個Host里面,否則部署到獨立的Host中是更好的選擇。Device對應(yīng)一個真實的物理設(shè)備。DeviceNode是設(shè)備的一個部件,Device至少有一個DeviceNode。每個DeviceNode可以發(fā)布一個設(shè)備服務(wù)。驅(qū)動即驅(qū)動程序,每個DevicdNode唯一對應(yīng)一個驅(qū)動,實現(xiàn)和硬件的功能交互。
3、OpenHarmony HDF驅(qū)動加載
HDF驅(qū)動框架提供把和配置的設(shè)備列表匹配成功的驅(qū)動程序加載起來的功能。
支持按需加載和按序加載兩種策略,具體設(shè)備的加載策略由配置文件中的preload字段來控制,配置值參考如下:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
(1)按需加載
- preload字段配置為0(DEVICE_PRELOAD_ENABLE),則系統(tǒng)啟動過程中默認加載。
- preload字段配置為1(DEVICE_PRELOAD_ENABLE_STEP2),當(dāng)系統(tǒng)支持快速啟動的時候,則在系統(tǒng)完成之后再加載這一類驅(qū)動,否則和DEVICE_PRELOAD_ENABLE含義相同。
- preload字段配置為2(DEVICE_PRELOAD_DISABLE),則系統(tǒng)啟動過程中默認不加載,支持后續(xù)動態(tài)加載,當(dāng)用戶態(tài)獲取驅(qū)動服務(wù)時,如果驅(qū)動服務(wù)不存在,HDF框架會嘗試動態(tài)加載該驅(qū)動。
(2)按序加載(默認加載策略)
配置文件中的priority(取值范圍為整數(shù)0到200)是用來表示host(驅(qū)動容器)和驅(qū)動的優(yōu)先級。不同的host內(nèi)的驅(qū)動,host的priority值越小,驅(qū)動加載優(yōu)先級越高;同一個host內(nèi)驅(qū)動的priority值越小,加載優(yōu)先級越高。
4、OpenHarmony HDF驅(qū)動服務(wù)管理
驅(qū)動服務(wù)是HDF驅(qū)動設(shè)備對外提供能力的對象,由HDF框架統(tǒng)一管理。驅(qū)動服務(wù)管理主要包含驅(qū)動服務(wù)的發(fā)布和獲取。
(1)驅(qū)動服務(wù)的發(fā)布策略
HDF框架定義了驅(qū)動對外發(fā)布服務(wù)的策略,由配置文件中的policy字段來控制,policy字段的取值范圍以及含義如下:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
(2)驅(qū)動服務(wù)的接口說明
針對驅(qū)動服務(wù)管理功能,HDF框架開放了以下接口供開發(fā)者調(diào)用,如下表所示:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
5、驅(qū)動消息機制管理
當(dāng)用戶態(tài)應(yīng)用和內(nèi)核態(tài)驅(qū)動需要交互時,可以使用HDF框架的消息機制來實現(xiàn)。
消息機制的功能主要有以下兩種:
- 用戶態(tài)應(yīng)用發(fā)送消息到驅(qū)動。
- 用戶態(tài)應(yīng)用接收驅(qū)動主動上報事件。
消息機制接口如下所示:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
6、配置樹配置
HCS(HDF Configuration Source)是HDF驅(qū)動框架的配置描述源碼,內(nèi)容以Key-Value為主要形式。它實現(xiàn)了配置代碼與驅(qū)動代碼解耦,便于開發(fā)者進行配置管理。
HC-GEN(HDF Configuration Generator)是HCS配置轉(zhuǎn)換工具,可以將HDF配置文件轉(zhuǎn)換為軟件可讀取的文件格式:
- 在弱性能環(huán)境中,轉(zhuǎn)換為配置樹源碼或配置樹宏定義,驅(qū)動可直接調(diào)用C代碼或宏式APIs獲取配置。
- 在高性能環(huán)境中,轉(zhuǎn)換為HCB(HDF Configuration Binary)二進制文件,驅(qū)動可使用HDF框架提供的配置解析接口獲取配置。
HCS經(jīng)過HC-GEN編譯生成HCB文件,HDF驅(qū)動框架中的HCS Parser模塊會從HCB文件中重建配置樹,HDF驅(qū)動模塊使用HCS Parser提供的配置讀取接口獲取配置內(nèi)容。
三、代碼解析
1、配置文件
(1)device_info.hcs
創(chuàng)建config/device_info.hcs,用于驅(qū)動設(shè)備描述,具體內(nèi)容如下:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
注意:
- device_rk3568_sample:為配置樹的類設(shè)備結(jié)點。
- deviceMatchAttr:關(guān)鍵字必須與config.hcs的match_attr匹配。
(2)config.hcs
創(chuàng)建config/config.hcs,用于定義私有變量,具體內(nèi)容如下:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
由于我們沒有用到其他私有變量,故不做定義。
(3)參與配置樹編譯
編輯//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,將device_info.hcs添加配置樹中。具體內(nèi)容如下所示:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
2、HDF驅(qū)動
(1)driver_hdf_sample.c
頭文件
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
定義打印標簽
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
建議讀者用HDF_LOGI、HDF_LOGE等打印信息。
驅(qū)動初始化
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
驅(qū)動釋放
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
驅(qū)動綁定
將驅(qū)動對外提供的服務(wù)能力接口綁定到HDF框架,通過struct IDeviceIoService設(shè)置Dispatch函數(shù)。
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
HdfSampleDriverDispatch()掛載載struct IDeviceIoService的函數(shù)指針成員Dispatch,它相當(dāng)于Linux的ioctl,可與應(yīng)用程序進行數(shù)據(jù)交互。
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
驅(qū)動注冊
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
(2)Makefile
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
(3)參與Linux內(nèi)核編譯
編輯//drivers/hdf_core/adapter/khdf/linux/Makefile,添加一段代碼,將sample驅(qū)動參與Linux內(nèi)核編譯中。具體如下所示:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
3、應(yīng)用程序
(1)sample_test.c
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
(2)BUILD.gn
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
(3)參與應(yīng)用程序編譯
編輯//vendor/lockzhiner/rk3568/samples/BUILD.gn,開啟sample編譯。具體如下:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
四、編譯說明
建議使用docker編譯方法,運行如下:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)
五、運行結(jié)果
該程序運行結(jié)果如下所示:
凌蒙派-RK3568開發(fā)板-基礎(chǔ)外設(shè)類:簡易HDF驅(qū)動-開源基礎(chǔ)軟件社區(qū)