HDF 驅(qū)動框架是 OpenAtom OpenHarmony(簡稱“OpenHarmony”)系統(tǒng)硬件生態(tài)開放的基礎(chǔ),為驅(qū)動開發(fā)者提供了驅(qū)動加載、驅(qū)動服務(wù)管理和驅(qū)動消息機(jī)制等驅(qū)動框架能力,同時還為開發(fā)者提供了規(guī)范的HDI硬件設(shè)備接口,讓開發(fā)者能屏蔽南向設(shè)備差異,提供更好的硬件。本文將為大家?guī)?HDI 硬件設(shè)備接口的介紹。

一、HDI介紹
HDI(Hardware Device Interface,硬件設(shè)備接口)是 HDF 驅(qū)動框架為開發(fā)者提供的硬件規(guī)范化描述性接口。在 OpenHarmony 分層結(jié)構(gòu)中,HDI 位于 “基礎(chǔ)系統(tǒng)服務(wù)層”和“設(shè)備抽象層(DAL)”之間。硬件設(shè)備通過 DAL 抽象化,并基于 IDL(Interface Description Language)接口描述語言描述后,為上層應(yīng)用或服務(wù)提供了規(guī)范的硬件設(shè)備接口。

圖2 OpenHarmony 分層結(jié)構(gòu)
HDI 支持“IPC 模式”及“直通模式”兩種調(diào)用方式。其中,IPC 模式即跨進(jìn)程通信模式,基于 binder 機(jī)制實(shí)現(xiàn),調(diào)用端通過 Proxy 代理庫調(diào)用 HDI 接口,具備良好的解耦性和安全性,是標(biāo)準(zhǔn)系統(tǒng)的默認(rèn)部署方式。直通模式,將 HDI 實(shí)現(xiàn)為共享庫,調(diào)用端使用 dlopen 加載 HDI 實(shí)現(xiàn)庫并直接調(diào)用 HDI 接口,是小型系統(tǒng)的默認(rèn)部署方式,同時還適用于對性能有特殊需求的標(biāo)準(zhǔn)系統(tǒng)模塊。

圖3 兩種調(diào)用方式
HDI 硬件設(shè)備接口的優(yōu)點(diǎn)用一句話總結(jié)就是:為硬件的接入提供了統(tǒng)一的實(shí)現(xiàn)通路。屏蔽了硬件接口的具體實(shí)現(xiàn),實(shí)現(xiàn)系統(tǒng)軟件與硬件的架構(gòu)解耦。讓開發(fā)者專注于硬件接口的使用,從而簡化開發(fā)過程,提升開發(fā)效率。
二、HDI實(shí)現(xiàn)
通過上文的介紹,相信很多小伙伴會有疑問,HDI 接口是怎么實(shí)現(xiàn)的呢?下面我們將為你介紹 IPC 模式下基于 C/S(Client-Server 客戶端與服務(wù)端)結(jié)構(gòu)的 HDI 接口實(shí)現(xiàn)。
2.1 IDL接口描述語言
為方便后文的理解,我們先簡單了解一下 IDL 接口描述語言。
IDL(Interface Description Language)是一類用來描述接口的語言,通過一種中立的方式來定義客戶端與服務(wù)端均認(rèn)可的編程接口,可以實(shí)現(xiàn)在二者間的跨進(jìn)程通信(IPC)??邕M(jìn)程通信意味著可以在一個進(jìn)程訪問另一個進(jìn)程的數(shù)據(jù),或調(diào)用另一個進(jìn)程的方法。通常把應(yīng)用接口提供方(供調(diào)用)稱為服務(wù)端,調(diào)用方稱為客戶端。
IDL 先把需要傳遞的對象分解成操作系統(tǒng)能夠理解的基本類型,然后根據(jù)接口聲明編譯,生成 IPC/RPC代理(Proxy)和樁(Stub)的 C/C++ 代碼,從而為調(diào)用者提供一致的接口和調(diào)用方式。

圖4 IDL IPC模式通信模型
2.2 基于IDL語言實(shí)現(xiàn)HDI接口
首先,使用 IDL 語法描述 HDI 接口并保存為.idl文件,然后編寫 .idl 文件的編譯腳本 BUILD.gn 文件,最后編譯 .idl 文件即可。下面我們將為大家演示電源子系統(tǒng)的 HDI 接口的實(shí)現(xiàn)過程。
(1)使用IDL語法編寫 .idl 文件
package ohos.hdi.power.v1_0;import ohos.hdi.power.v1_0.IPowerHdiCallback;import ohos.hdi.power.v1_0.PowerTypes;interface IPowerInterface {RegisterCallback([in] IPowerHdiCallback ipowerHdiCallback);StartSuspend();StopSuspend();ForceSuspend();SuspendBlock([in] String name);SuspendUnblock([in] String name);PowerDump([out] String info);}
● 如果需要從服務(wù)端回調(diào),可以定義 callback 接口類 IPowerHdiCallback.idl
package ohos.hdi.power.v1_0;[] interface IPowerHdiCallback {OnSuspend();OnWakeup();}
● 如果 interface 中用到了自定義數(shù)據(jù)類型,將自定義類型定義到 powerTypes.idl
package ohos.hdi.power.v1_0;enum PowerHdfCmd {CMD_REGISTER_CALLBCK = 0,CMD_START_SUSPEND,CMD_STOP_SUSPEND,CMD_FORCE_SUSPEND,CMD_SUSPEND_BLOCK,CMD_SUSPEND_UNBLOCK,CMD_DUMP,};enum PowerHdfCallbackCmd {CMD_ON_SUSPEND = 0,CMD_ON_WAKEUP,};enum PowerHdfState {AWAKE = 0,INACTIVE,SLEEP,};
(2)編寫 .idl 文件的編譯腳本 BUILD.gn
import("//drivers/adapter/uhdf2/hdi.gni")if (defined(ohos_lite)) {group("libpower_proxy_1.0") {deps = []public_configs = []}} else {hdi("power") {module_name = "power_interface_service"sources = ["IPowerHdiCallback.idl","IPowerInterface.idl","PowerTypes.idl",]language = "cpp" subsystem_name = "hdf" part_name = "power_device_driver" }}
(3)編譯 .idl文件
使用編譯工具 hdi-gen 編譯 IDL 文件,IDL 文件在編譯過程中轉(zhuǎn)換為 C/C++ 語言的函數(shù)接口聲明、客戶端與服務(wù)端 IPC 相關(guān)過程代碼,開發(fā)者只需要基于生成的 power.h 函數(shù)接口實(shí)現(xiàn)具體服務(wù)功能即可。
編譯后生成代碼在 out/product/gen/drivers/interface/power 中,接口代碼如下:
namespace OHOS {namespace HDI {namespace Power {namespace V1_0 {using namespace OHOS;enum {CMD_POWER_INTERFACE_REGISTER_CALLBACK,CMD_POWER_INTERFACE_START_SUSPEND,CMD_POWER_INTERFACE_STOP_SUSPEND,CMD_POWER_INTERFACE_FORCE_SUSPEND,CMD_POWER_INTERFACE_SUSPEND_BLOCK,CMD_POWER_INTERFACE_SUSPEND_UNBLOCK,CMD_POWER_INTERFACE_POWER_DUMP,CMD_POWER_INTERFACE_GET_VERSION,};class IPowerInterface : public IRemoteBroker {public:DECLARE_INTERFACE_DESCRIPTOR(u"ohos.hdi.power.v1_0.IPowerInterface");virtual ~IPowerInterface() = default;static sptrGet() ;static sptrGetInstance(const std::string& serviceName) ;virtual int32_t RegisterCallback(const sptr& ipowerHdiCallback ) = 0;virtual int32_t StartSuspend() = 0;virtual int32_t StopSuspend() = 0;virtual int32_t ForceSuspend() = 0;virtual int32_t SuspendBlock(const std::string& name) = 0;virtual int32_t SuspendUnblock(const std::string& name) = 0;virtual int32_t PowerDump(std::string& info) = 0;virtual int32_t GetVersion(uint32_t& majorVer, uint32_t& minorVer) = 0;};} // V1_0} // Power} // HDI}//OHOS
(4)實(shí)現(xiàn)HDI接口
● 實(shí)現(xiàn) UHDF Driver,用于將 HDI 實(shí)現(xiàn)加載為獨(dú)立進(jìn)程,并基于 HDF 驅(qū)動框架發(fā)布設(shè)備服務(wù)。
static int32_t PowerInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,struct HdfSBuf *reply){......return hdfPowerInterfaceHost->service->OnRemoteRequest(cmdId, *dataParcel, *replyParcel, option); // 將接口調(diào)用轉(zhuǎn)發(fā)到stub實(shí)現(xiàn)}static int HdfPowerInterfaceDriverBind(struct HdfDeviceObject *deviceObject){......hdfPowerInterfaceHost->ioservice.Dispatch = PowerInterfaceDriverDispatch;hdfPowerInterfaceHost->ioservice.Open = NULL;hdfPowerInterfaceHost->ioservice.Release = NULL;hdfPowerInterfaceHost->service = new PowerInterfaceImpl();deviceObject->service = &hdfPowerInterfaceHost->ioservice;return HDF_SUCCESS;}......struct HdfDriverEntry g_powerinterfaceDriverEntry = {.moduleVersion = 1,.moduleName = "power_interface_service",.Bind = HdfPowerInterfaceDriverBind,.Init = HdfPowerInterfaceDriverInit,.Release = HdfPowerInterfaceDriverRelease,};
● 實(shí)現(xiàn) HDI 接口
/* 繼承PowerInterfaceStub并實(shí)現(xiàn)IPowerInterface 中的接口*/class PowerInterfaceImpl : public PowerInterfaceStub {public:virtual ~PowerInterfaceImpl() {}int32_t RegisterCallback(const sptr& ipowerHdiCallback) override; int32_t StartSuspend() override;int32_t StopSuspend() override;int32_t ForceSuspend() override;int32_t SuspendBlock(const std::string& name) override;int32_t SuspendUnblock(const std::string& name) override;int32_t PowerDump(std::string& info) override;};// 在cpp中對相關(guān)接口進(jìn)行實(shí)現(xiàn),其中調(diào)用了內(nèi)核相關(guān)接口,實(shí)現(xiàn)了具體功能int32_t PowerInterfaceImpl::StopSuspend(){suspendRetry_ = false;return HDF_SUCCESS;}int32_t PowerInterfaceImpl::ForceSuspend(){suspendRetry_ = false;NotifyCallback(CMD_ON_SUSPEND);DoSuspend();NotifyCallback(CMD_ON_WAKEUP);return HDF_SUCCESS;}int32_t PowerInterfaceImpl::SuspendBlock(const std::string& name){std::lock_guard<std::mutex> lock(mutex_);if (name.empty()) {return HDF_ERR_INVALID_PARAM;}UniqueFd fd(TEMP_FAILURE_RETRY(open(LOCK_PATH, O_RDWR | O_CLOEXEC)));bool ret = SaveStringToFd(fd, name);if (!ret) {return HDF_FAILURE;}return HDF_SUCCESS;}
三、HDI使用
通過上文的介紹,相信大家已經(jīng)對 HDI 有了一定的了解,下面我們將為大家介紹 HDI 的使用,在直通模式下,對 HDI 接口調(diào)用為同一進(jìn)程空間函數(shù)調(diào)用,過程較為直接,這里我們重點(diǎn)闡述 IPC 模式下的調(diào)用原理,然后通過 CPP 語言來展示電源子系統(tǒng) HDI 的調(diào)用。
3.1 調(diào)用原理
在 IPC 模式下,當(dāng)系統(tǒng)服務(wù)調(diào)用 HDI 接口時,通過 proxy 庫將函數(shù)調(diào)用轉(zhuǎn)換為 IPC 請求,將接口調(diào)用的參數(shù)進(jìn)行序列化;IPC 請求通過 IPC 框架發(fā)送到服務(wù)端,請求將被 stub 庫先處理,然后對接口調(diào)用的參數(shù)進(jìn)行反序列化,再轉(zhuǎn)換成對服務(wù)實(shí)現(xiàn)的函數(shù)調(diào)用,從而實(shí)現(xiàn)接口調(diào)用過程。

圖5 HDI調(diào)用過程
3.2 基于CPP語言的使用
上文已經(jīng)編譯生成了電源子系統(tǒng)的 HDI 接口,下面我們來看看如何使用 CPP 語言來調(diào)用 HDI 接口吧。
(1)客戶端在BUILD.gn中增加依賴://drivers/interface/foo/v1.0:libfoo_proxy_1.0"
ohos_executable("call_foo_hdi") {sources = ["src/call_foo_hdi.cpp",]deps = ["http://drivers/interface/foo/v1.0:libfoo_proxy_1.0",]external_deps = ["hiviewdfx_hilog_native:libhilog","ipc:ipc_core","utils_base:utils",]part_name = "bar"subsystem_name = "bar_subsystem"}
(2)在實(shí)現(xiàn)電源子系統(tǒng)的代碼中調(diào)用 HDI 接口,代碼如下:
using namespace OHOS::V1_0; //使用HDI接口命名空間namespace OHOS {namespace PowerMgr {sptrpowerInterface = nullptr; SystemSuspendController::SystemSuspendController(){sptrg_callback = new PowerHdiCallbackImpl(); powerInterface = IPowerInterface::Get(); //調(diào)用接口實(shí)例化接口獲取客戶端實(shí)例if (powerInterface == nullptr) {POWER_HILOGE(COMP_SVC, "The hdf interface is null");return;}powerInterface->RegisterCallback(g_callback); // 調(diào)用HDI接口注冊電源事件回調(diào)}
四、結(jié)語
以上就是本文全部內(nèi)容,我們在這里簡單介紹了HDI接口的實(shí)現(xiàn)思路及使用,對于廣大南向開發(fā)者,我們還在社區(qū)提供了詳細(xì)的HDI接口實(shí)現(xiàn)指導(dǎo),歡迎大家在gitee社區(qū)參與更多討論。
社區(qū)鏈接:
https://gitee.com/openharmony/drivers_interface
審核編輯 :李倩
-
接口
+關(guān)注
關(guān)注
33文章
9364瀏覽量
155863 -
HDI
+關(guān)注
關(guān)注
7文章
219瀏覽量
22538
原文標(biāo)題:OpenHarmony 3.1 Release版本關(guān)鍵特性解析——HDI硬件設(shè)備接口介紹
文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
USB 接口無法識別外接設(shè)備怎么辦??
HDI盲埋孔PCB階數(shù)區(qū)分方法解析
眾陽電路HDI剛?cè)岚?b class='flag-5'>介紹(一)
RCA接口適用哪些設(shè)備
如何連接RCA接口的設(shè)備
HDI技術(shù)—設(shè)計(jì)奧秘與PCB制造的極致工藝之旅
hdi高密度互連PCB電金適用性
高密度PCB(HDI)制造檢驗(yàn)標(biāo)準(zhǔn)
HDI盲埋孔工藝及制程能力你了解多少?
HDI盲埋孔工藝及制程能力你了解多少?
HDI線路板和多層線路板的五大區(qū)別
生產(chǎn)HDI線路板需要解決的主要問題
HDI技術(shù)在5G通信設(shè)備中的信號完整性優(yōu)化方法
淺談HDI同位二階的實(shí)現(xiàn)方式

HDI硬件設(shè)備接口介紹
評論