0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HDI接口中如何实现驱动入口

HarmonyOS开发者 来源:OpenAtom OpenHarmony 作者: OAOH 2021-09-08 11:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

HDI接口概述

HDF 驱动框架的一个重要功能是为系统提供稳定的统一的硬件接口,这样才能保证系统服务可以运行在不同硬件上而不需要额外的适配工作,而HDI(Hardware Device Interfaces)正是为了实现该目的而设计。

HDI 是对硬件功能的较高层次抽象接口,各类外设完成 HDI 接口定义后便只会在 HDI 的兼容性规则下进行变更,从而保证接口的稳定性。具体的驱动实现不需要再重复定义 HDI 接口,只需要按需实现即可接入系统功能。

在不同量级的 OpenHarmony 系统上,HDI 存在两种部署形态,IPC 模式和直通模式。

在轻量级 OpenHarmony 系统上,出于减小系统性能负载考虑,HDI 实现为用户态共享库,由系统服务直接加载 HDI 实现到自己进程中函数调用使用。HDI 实现封装具体的用户态-内核态交互过程,当需要访问驱动程序时使用 IO Service 请求将消息通过 system call 方式调用到内核驱动实现。

在 OpenHarmony 系统上,HDI 以独立服务进程方式部署,系统服务只加载 HDI 客户端实现到自己进程中,实际业务运行在独立进程中,客户端通过 IPC 与服务端交互,便于架构解耦、权限管理。

HDI接口实现

直通模式为函数实现方式,无论调用还是实现都不需要其他组件支持即可实现,这里将重点分析 IPC 模式的实现。

HDI发布

HDI IPC 模式基于 OpenHarmony 系统通信框架的通用模型,但是因为驱动很多时候涉及到底层操作和多系统迁移的场景而使用C语言编写,所以驱动框架还提供了 HDI 服务的 C 语言实现的基础组件,C++实现则主要使用系统通信框架组件。

HDI 服务发布基于 UHDF(用户态 HDF 驱动框架)实现,通用的服务发布实现如下。

1.实现驱动入口

int SampleDriverBind(struct HdfDeviceObject *deviceObject){ HDF_LOGE(“SampleDriverBind enter!”); static struct IDeviceIoService testService = { .Dispatch = SampleServiceDispatch, // 服务回调接口 }; deviceObject-》service = &testService; return HDF_SUCCESS;} int SampleDriverInit(struct HdfDeviceObject *deviceObject){ HDF_LOGE(“SampleDriverInit enter”); return HDF_SUCCESS;} void SampleDriverRelease(struct HdfDeviceObject *deviceObject){ HDF_LOGE(“SampleDriverRelease enter”); return;} struct HdfDriverEntry g_sampleDriverEntry = { .moduleVersion = 1, .moduleName = “sample_driver”, .Bind = SampleDriverBind, .Init = SampleDriverInit, .Release = SampleDriverRelease,};

HDF_INIT(g_sampleDriverEntry);

首先要添加一个 UHDF 驱动用于发布 IoService 服务,IoService 设备服务即为 HDI 服务实体。实现方式与 KHDF 驱动一致。

2.实现服务响应接口

int32_t SampleServiceOnRemoteRequest(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply){ switch (cmdId) { case SAMPLE_SERVICE_PING: return SampleServiceStubPing(client, data, reply); … … default: HDF_LOGE(“SampleServiceDispatch: not support cmd %d”, cmdId); return HDF_ERR_INVALID_PARAM; }}static int32_t SampleServiceDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply){ return SampleServiceOnRemoteRequest(client, cmdId, data, reply);}

当收到 HDI 调用时,服务响应接口“SampleServiceDispatch”将会被调用。

client 调用者对象,在用户态驱动中暂时未支持

cmdId 调用命令字,用于区分调用的 API

data 调用入参序列化对象,在 IPC 调用场景为 parcel 对象的 C 语言封装,入参需要使用序列化接口从 data 对象中获取后再使用

reply 调用出参对象,需要返回给调用的信息写入该序列化对象

如果 C++实现客户端可以使用下面接口将 sbuf 对象转换为 parcel 对象后操作:

int32_t SbufToParcel(struct HdfSBuf *sbuf, OHOS::MessageParcel **parcel);

3.UHDF 驱动配置

platform :: host { hostName = “sample_host”; priority = 50; sample_device :: device { device0 :: deviceNode { policy = 2; priority = 100; moduleName = “libsample_driver.z.so”; serviceName = “sample_driver_service”; } }}

参数说明:

host 一个 host 节点即为一个独立进程,如果需要独立进程,新增属于自己的 host 节点

policy 服务发布策略,HDI 服务设置为 2

moduleName 驱动实现库名

serviceName 服务名称,请保持全局唯一性

因为 HDI 服务 C 和 C++实现使用的 IPC 组件不一样,面向对象实现也不一致,所以在具体实现上存在一些差异。

HDI基础组件 UHDF 框架为了支持 HDI 实现,提供了以下基础组件(仅用于 C 语言 HDI 实现):

SBuf

SBuf 是同时支持 KHDF 和 UHDF 驱动 IoService 消息序列化的工具对象。在 UHDF IPC 通信场景中,SBuf 可以与系统 IPC 框架序列化对象 MessageParcel 对象(仅支持 C++)相互转换,从而实现 C 和 C++实现的 IPC 互通。

常用 API 如下:

struct HdfSBuf;struct HdfSbufImpl;struct HdfRemoteService;

/** * @brief HdfSBuf类型定义。 * * @since 1.0 */enum HdfSbufType { SBUF_RAW = 0, /* 用于用户态内核态通信的sbuf类型 */ SBUF_IPC, /* 用于跨进程通信的sbuf类型 */ SBUF_IPC_HW, /* 用于扩展的预留类型 */ SBUF_TYPE_MAX, /* sbuf类型最大值 */};

上述接口均有对应的写入接口,不再一一列举,可查阅官网API参考文档。

RemoteService

RemoteService 对象和系统 IPC 框架中的 IRemoteObject 对象(仅支持 C++)对应并可以相互转换,表示一个 IPC 对象。相关 API 说明:

// 消息分发器,用于服务端响应调用或者在客户端发起调用struct HdfRemoteDispatcher { int (*Dispatch)(struct HdfRemoteService *, int, struct HdfSBuf *, struct HdfSBuf *);};

// RemoteService 死亡回调对象struct HdfDeathRecipient { void (*OnRemoteDied)(struct HdfDeathRecipient *, struct HdfRemoteService *);};

struct HdfRemoteService { struct HdfObject object_; struct HdfObject *target; struct HdfRemoteDispatcher *dispatcher; bool isHw;};// 以自定义的消息分发器实例化一个RemoteServicestruct HdfRemoteService *HdfRemoteServiceObtain( struct HdfObject *object, struct HdfRemoteDispatcher *dispatcher);

// 回收RemoteService对象void HdfRemoteServiceRecycle(struct HdfRemoteService *service);

// 添加RemoteService的死亡通知,如果对应RemoteService的进程异常退出,HdfDeathRecipient的回调接口将被调用void HdfRemoteServiceAddDeathRecipient(struct HdfRemoteService *service, struct HdfDeathRecipient *recipient);

基于 RemoteService 实现一个服务端的示例:

int SampleServiceStubDispatch( struct HdfRemoteService* service, int code, struct HdfSBuf *data, struct HdfSBuf *reply){ // IPC 调用响应接口 int ret = HDF_FAILURE; switch (code) { case SAMPLE_IF_0: { // do something break; } default: { ret = HDF_ERR_INVALID_PARAM; } } return ret;}bool SampleStubConstruct(){ // 构造消息分发器,实现消息处理回调 static struct HdfRemoteDispatcher dispatcher = { .Dispatch = SampleServiceStubDispatch};// 实例化RemoteService inst-》remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher); if (inst-》remote == NULL) { HDF_LOGE(“Device service manager failed to obtain remote service”); return false;}… …

直接基于 RemoteService 实现服务端只适用于需要实现匿名 IPC 服务的情况,基于 UHDF 发布 HDI 服务只需要实现 Driver 绑定的 IoService 即可。

RemoteService 客户端对象只能从 SBuf HdfSBufReadRemoteService 接口获取。

HDI实现

Driver 为 HDI 服务的驱动入口实现

IoService 为 HDI 服务的服务入口实现,IoService 的 Dispatch 方法中调用 ServiceStub 中的真正服务响应接口(OnRemoteRequest)

ServiceStub 为服务端实现对象,主要处理与 IPC 相关的业务逻辑,在这里完成参数反序列化后调用真正的 Service 实现接口,即 ServiceImpl 接口

ServiceImpl 为 HDI 接口的真正实现,这里不关注 IPC 过程,只实现函数接口。

驱动框架提供了实现的样例代码,可参考 gitee driver 代码仓。

HDI接口调用

HDI驱动框架HDI接口

HDI 服务管理功能由驱动框架 DeviceManager 实现,所以驱动框架提供了 HDI 服务管理相关 HDI 接口。

C++实现:

namespace OHOS {namespace HDI {namespace ServiceManager {namespace V1_0 {

struct IServiceManager : public IRemoteBroker {public: DECLARE_INTERFACE_DESCRIPTOR(u“HDI.IServiceManager.V1_0”); // get()静态方法用于获取IServiceManager对象实例 static ::sptr《IServiceManager》 Get(); // GetService()接口是真正提供的HDI接口,用于查询并获取其他HDI服务的客户端对象 virtual ::sptr《IRemoteObject》 GetService(const char* serviceName) = 0;};} // namespace V1_0} // namespace ServiceManager} // namespace HDI} // namespace OHOS

C 实现:

#ifdef __cplusplusextern “C” {#endif /* __cplusplus */

struct HDIServiceManager { struct HdfRemoteService *remote;

struct HdfRemoteService *(*GetService)(struct HDIServiceManager *self, const char* serviceName);};

struct HDIServiceManager *HDIServiceManagerGet(void);void HDIServiceManagerRelease(struct HDIServiceManager *servmgr);

#ifdef __cplusplus}#endif /* __cplusplus */

C 语言因为缺少原生的面向对象支持,这里我们采用 OOC 的实现,函数方法 HDIServiceManagerGet/Release 用于 HDIServiceManager 对象的实例化和释放,HDI 接口关联在接口对象内部成员中,与 C++实现类似。

HDI客户端实现

HDI 客户端同时支持 C 和 C++实现,实现方法较为简单,只需 realize HDI 接口类即可。提供 C++实现基于系统 IPC 子系统的统一模型,C 语言基于 RemoteService 和 SBuf 组件实现,但是有一些公共的约定:

1.客户端提供接口对象,接口与对象绑定且必须与 HDI 一致

2.提供服务接口对象的实例化和释放接口。

3.客户端实现 IPC 过程,只为调用者暴露函数化接口。

HDI接口调用

HDI 客户端接口已经提供了服务获取接口,调用者调用服务获取接口后再调用服务对象方法即可完成 HDI 调用。

这里以服务管理 HDI 接口为例:

C++接口调用:

#include 《iservmgr_hdi.h》

void GetTestService(){ auto servmgr = IServiceManager::Get(); if (servmgr == nullptr) { HDF_LOGE(“failed to get IServiceManager”); return; }

auto sampleService = servmgr-》GetService(TEST_SERVICE_NAME); if (sampleService == nullptr) { HDF_LOGE(“failed to get TEST_SERVICE”); return; } // do something}

C 接口调用:

#include 《servmgr_hdi.h》

void GetTestService(){ struct HDIServiceManager *servmgr = HDIServiceManagerGet(); if (servmgr == nullptr) { HDF_LOGE(“failed to get IServiceManager”); return; }

struct HdfRemoteService *sampleService = servmgr-》GetService(servmgr, TEST_SERVICE_NAME); if (sampleService == nullptr) { HDF_LOGE(“failed to get TEST_SERVICE”); return; } // do something}

总结

本文介绍了 HDI 的总体方案,重点介绍了 HDI 的 IPC 模式具体实现方法和驱动框架能力,相信对读者理解和使用 HDI 有所帮助。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    9591

    浏览量

    157598
  • HDI
    HDI
    +关注

    关注

    7

    文章

    227

    浏览量

    22799
  • HarmonyOS
    +关注

    关注

    80

    文章

    2157

    浏览量

    36280

原文标题:OpenHarmony HDF HDI基础能力分析与使用

文章出处:【微信号:HarmonyOS_Dev,微信公众号:HarmonyOS开发者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何设置HDI PCB布局?

    如何设置HDI PCB布局 在电子设计领域,HDI(High Density Interconnect)PCB,即高密度互连印刷电路板,已成为现代电子设备中不可或缺的关键组件。其以高集成度、小体
    的头像 发表于 03-30 17:01 963次阅读
    如何设置<b class='flag-5'>HDI</b> PCB布局?

    泰克科技示波器和分析工具在高速接口中的应用优势

    高速接口需要精确的验证和工作流程。泰克为跨PCIe、DDR、USB、LPDDR和新兴SerDes标准的数千兆比特信号提供行业领先的解决方案。
    的头像 发表于 03-26 15:58 541次阅读
    泰克科技示波器和分析工具在高速<b class='flag-5'>接口中</b>的应用优势

    MAX3816A:DVI、HDMI和VGA接口中DDC的I2C 2线扩展器

    MAX3816A:DVI、HDMI和VGA接口中DDC的I2C 2线扩展器 在当今的数字显示领域,DVI、HDMI和VGA接口广泛应用于各种设备中,如高清电视、显示器和计算机监视器等。然而,长距离
    的头像 发表于 02-28 16:05 332次阅读

    MAX6959:2线接口LED显示驱动器的设计指南

    MAX6958/MAX6959:2线接口LED显示驱动器的设计指南 在电子设计领域,LED显示驱动器是实现数字显示功能的关键组件。今天,我们来深入探讨MAXIM公司的MAX6958/M
    的头像 发表于 02-03 15:25 284次阅读

    京东商品详情API接口:电商数据驱动的核心入口解析

    在数字经济深入渗透电商行业的今天,数据已成为企业优化运营、提升竞争力的核心资产。京东作为国内头部电商平台,沉淀了海量标准化商品数据与动态交易信息,而京东商品详情API接口(核心接口名如
    的头像 发表于 01-26 11:52 264次阅读

    HDI线路板的应用领域:从通信到军事设备

    HDI线路板凭借高密度、高可靠性的特点,广泛应用于通信、军事设备、消费电子、汽车电子及航空航天等领域。以下是具体应用场景: 通信设备 HDI板用于5G基站、路由器、交换机等,支持高频信号传输和高速
    的头像 发表于 12-16 16:05 1595次阅读

    原厂 FZH1697 带键盘扫描接口的LCD驱动控制专用电路

    背光驱动; 4通用输入口,可连接拨轮式电子编码开关1/2或1/3LCD驱动偏压可选LCD工作电压可调串行接口(CLK,STB,DIO) 振荡方式:内置RC振荡,典型振荡频率为128KH
    发表于 11-07 09:43

    图文详情编辑接口的设计与实现

    。本文将从接口设计原则、核心功能、技术实现到代码示例,逐步解析如何构建一个健壮的图文详情编辑接口。我们将聚焦于RESTful API设计,确保接口安全、可扩展且高性能。 1.
    的头像 发表于 10-23 16:37 489次阅读
    图文详情编辑<b class='flag-5'>接口</b>的设计与<b class='flag-5'>实现</b>

    E203串口中断使用总结

    以上函数的设置后,就可以在中断服务函数中写下自己需要的中断处理功能,并且在 main() 函数中写下“my_uart_init()”,就能实现口中断。 二、串口接收字符串 首先需要注意的是,由于
    发表于 10-22 07:34

    商品图片批量上传接口设计与实现

    ? 在电商平台或内容管理系统中,商品图片的高效管理是核心需求之一。批量上传接口允许用户一次性上传多张图片,显著提升操作效率。本文将逐步介绍如何设计并实现一个可靠的商品图片批量上传接口,涵盖接口
    的头像 发表于 10-13 15:25 547次阅读

    嵌入式接口通识知识之Ethernet接口

    ,是MII接口的一半;TX_EN(Transmit Enable):数据发送使能信号,与MII接口中的该信号线功能一样;RX_ER(Receive Error):数据接收错误提示信号,与MII接口中
    发表于 09-16 17:27

    增长新引擎!思瑞浦接口驱动芯片驶入快车道

    聚焦模拟和数模混合在工业、汽车、通信和新能源应用中,接口驱动产品有着不可或缺的作用。思瑞浦是最早布局接口驱动的国内模拟半导体公司之一,公司在接口
    的头像 发表于 09-14 22:15 914次阅读
    增长新引擎!思瑞浦<b class='flag-5'>接口</b>与<b class='flag-5'>驱动</b>芯片驶入快车道

    HDI盲埋孔PCB阶数区分方法解析

    HDI盲埋孔PCB的阶数是区分其结构复杂度的关键指标,主要通过增层次数、钻孔工艺及连接层数来综合判断,具体区分方法如下: 一、基于增层次数的阶数定义 HDI板结构通常以“a+N+a”或
    的头像 发表于 08-05 10:34 4797次阅读
    <b class='flag-5'>HDI</b>盲埋孔PCB阶数区分方法解析

    抗辐照芯片在微小卫星载荷通讯接口中的实践探索

    摘要: 在微小卫星技术蓬勃发展的当下,其在复杂太空辐射环境中的可靠性面临诸多挑战。通讯接口作为卫星载荷间及与地面传输数据的关键部件,其抗辐照能力至关重要。本文聚焦于抗辐照芯片在微小卫星载荷通讯接口中
    的头像 发表于 06-07 12:17 1094次阅读

    众阳电路HDI刚柔板介绍(一)

    随着电子产品向轻薄短小、高性能及多功能化方向发展,作为电子产品元器件支撑体的印制线路板(PCB)也需要向布线高密度化、轻薄化方向发展。高密度布线、高接点数的高密度互连(HDI)技术和可实现立体三维
    的头像 发表于 06-02 19:38 1046次阅读
    众阳电路<b class='flag-5'>HDI</b>刚柔板介绍(一)