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