OpenHarmony中基于HDF框架的驱动开发和使用

这篇具有很好参考价值的文章主要介绍了OpenHarmony中基于HDF框架的驱动开发和使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

代码版本:openharmony 3.2 release

主要内容

  1.         HDF框架基础知识
  2.         HDF驱动框架的开发
  3.         HDF驱动框架的应用

HDF框架基础知识 

HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理和驱动消息机制。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。

HDF驱动框架架构图:

openharmony hdi,驱动开发

HDF驱动架构主要组成部分:

  • HDI(Hardware Device Interface,硬件设备统一接口)层:通过规范化的设备接口标准,为系统提供统一、稳定的硬件设备操作接口。

  • HDF驱动框架:提供统一的硬件资源管理、驱动加载管理、设备节点管理、设备电源管理以及驱动服务模型等功能,需要包含设备管理、服务管理、DeviceHost、PnPManager等模块。

  • 统一的配置界面:支持硬件资源的抽象描述,屏蔽硬件差异,可以支撑开发者开发出与配置信息不绑定的通用驱动代码,提升开发及迁移效率,并可通过HC-Gen等工具快捷生成配置文件。

  • 操作系统抽象层(OSAL,Operating System Abstraction Layer):提供统一封装的内核操作相关接口,屏蔽不同系统操作差异,包含内存、锁、线程、信号量等接口。

  • 平台驱动:为外设驱动提供Board硬件(如:I2C/SPI/UART总线等平台资源)操作统一接口,同时对Board硬件操作进行统一的适配接口抽象以便于不同平台迁移。

  • 外设驱动模型:面向外设驱动,提供常见的驱动抽象模型,主要达成两个目的,提供标准化的器件驱动,开发者无需独立开发,通过配置即可完成驱动的部署;提供驱动模型抽象,屏蔽驱动与不同系统组件间的交互,使得驱动更具备通用性

以上的基础知识我也是从官方gitee中复制过来的,想具体了解的访问下面网址即可:

docs: OpenHarmony documentation | OpenHarmony开发者文档 - Gitee.comhttps://gitee.com/openharmony/docs/tree/master/zh-cn/device-dev/driver

HDF驱动框架的开发:

基于HDF框架的驱动开发主要分为三个部分:实例化驱动入口、驱动编译配置和驱动配置属性。详细开发流程如下所示:

2.1、实例化驱动入口:

驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。

一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。

在//drivers/hdf_core/adapter/khdf/linux目录下新建个名为sample_test目录,再创建一个驱动入口代码。

static int32_t HdfSampleDriverDispatch(
    struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
{
    HDF_LOGI("%{public}s: received cmd %{public}d", __func__, id);
    if (id == SAMPLE_WRITE_READ) {                         //接收用户的命令参数
        const char *readData = HdfSbufReadString(data);    //驱动读取用户的数据
        if (readData != NULL) {
            HDF_LOGE("%{public}s: read data is: %{public}s", __func__, readData);
        }
        if (!HdfSbufWriteInt32(reply, INT32_MAX)) {            //驱动返回给用户的数据
            HDF_LOGE("%{public}s: reply int32 fail", __func__);
        }
        return HdfDeviceSendEvent(client->device, id, data);
    }
    return HDF_FAILURE;
}

static void HdflDriverRelease(struct HdfDeviceObject *deviceObject)
{
    // release resources here
    return;
}

static int HdfDriverBind(struct HdfDeviceObject *deviceObject)
{
    if (deviceObject == NULL) {
        return HDF_FAILURE;
    }
    static struct IDeviceIoService testService = {
        .Dispatch = HdfSampleDriverDispatch,
    };
    deviceObject->service = &testService;
    return HDF_SUCCESS;
}

static int HdfDriverInit(struct HdfDeviceObject *deviceObject)
{
    if (deviceObject == NULL) {
        HDF_LOGE("%{public}s::ptr is null!", __func__);
        return HDF_FAILURE;
    }
    HDF_LOGI("Sample driver Init success");
    return HDF_SUCCESS;
}


static struct HdfDriverEntry DriverEntry = {
    .moduleVersion = 1,
    .moduleName = "sample_test",
    .Bind = HdfDriverBind,
    .Init = HdfDriverInit,
    .Release = HdflDriverRelease,
};
HDF_INIT(DriverEntry);

2.2、驱动编译配置:

完成驱动入口编写后,在驱动文件当前目录下添加一个Makefile文件,把驱动调用的头文件添加进来,然后再将所要编译的文件写进去,我没有用config配置的方式直接用的-y,这样比较简单些。

include drivers/hdf/khdf/platform/platform.mk
obj-y  += sample_tset.o

还要将上一个目录的的文件的编译加进编译系统里面去,在当前驱动文件的上一级目录(//drivers/hdf_core/adapter/khdf/linux)中的Makefile中添加进这样一句话,为了避免麻烦还是选择-y的方式编译。

obj-y += sample_test/

2.3、驱动配置属性

在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode信息:

device_sample_test :: device {                  // sample_test设备
       device0 :: deviceNode {             // sample_test设备下的具体某个设备节点的配置
              policy = 2;                     // 驱动服务发布策略
              priority = 110;                 // 驱动启动优先级
              permission = 0644;              // 驱动创建设备节点权限
              moduleName = "sample_test";      // 驱动名称,必须和驱动入口结构的moduleName值一致
              serviceName = "sample_test_service";    // 驱动对外发布服务的名称,必须唯一
       }
}
成员名
policy 驱动服务发布的策略,I2C管理器具体配置为2,表示驱动对内核态和用户态都发布服务
priority 驱动启动优先级(0-200),值越大优先级越低。I2C管理器具体配置为50
permission 驱动创建设备节点权限,I2C管理器具体配置为0664
moduleName 驱动名称,I2C管理器固定为HDF_PLATFORM_I2C_MANAGER
serviceName 驱动对外发布服务的名称,I2C管理器服务名设置为HDF_PLATFORM_I2C_MANAGER
deviceMatchAttr 驱动私有数据匹配的关键字,I2C管理器设置为hdf_platform_i2c_manager

以上步骤操作完之后,再次编译的时候就会将sample_test.c编译为sample_test.o,将固件烧录进系统里面在/dev目录下就会有一个名为sample_test的设备

HDF框架的应用

应用程序通过服务名绑定驱动程序,和驱动建立联系,建立完之后就可以对这个驱动设备进行操作了,此处的sample_test_NAME要和上文2.3中的serviceName保持一致

#define sample_test_NAME "sample_test_service"

serv = HdfIoServiceBind(sample_test_NAME );
if(serv == NULL){
    printf("fail to get service %s \n", sample_test_NAME );
    return HDF_FAILURE;
}
static int SendEvent(struct HdfIoService *serv, char *eventData)
{
    int ret = 0;
    struct HdfSBuf *data = HdfSbufObtainDefaultSize();     //获取data缓冲区
    if (data == NULL) {
        HDF_LOGE("fail to obtain sbuf data");
        return 1;
    }

    struct HdfSBuf *reply = HdfSbufObtainDefaultSize();    //获取reply缓冲区
    if (reply == NULL) {
        HDF_LOGE("fail to obtain sbuf reply");
        ret = HDF_DEV_ERR_NO_MEMORY;
        goto out;
    }

    if (!HdfSbufWriteString(data, eventData)) {            //将eventData写入data缓冲区
        HDF_LOGE("fail to write sbuf");
        ret = HDF_FAILURE;
        goto out;
    }

    //调用 Dispatch 将数据发送给驱动,SAMPLE_WRITE_READ为传入的命令参数
    ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("fail to send service call");
        goto out;
    }

    int replyData = 0;
    if (!HdfSbufReadInt32(reply, &replyData)) {            //读取驱动的返回值
        HDF_LOGE("fail to get service call reply");
        ret = HDF_ERR_INVALID_OBJECT;
        goto out;
    }
    HDF_LOGI("Get reply is: %{public}d", replyData);
out:
    HdfSbufRecycle(data);
    HdfSbufRecycle(reply);
    return ret;
}

编译应用的Build.gn文件:文章来源地址https://www.toymoban.com/news/detail-829013.html

    include_dirs = [
      "$HDF_FRAMEWORKS/ability/sbuf/include",
      "$HDF_FRAMEWORKS/core/shared/include",
      "$HDF_FRAMEWORKS/core/host/include",
      "$HDF_FRAMEWORKS/core/master/include",
      "$HDF_FRAMEWORKS/include/platform",
      "$HDF_FRAMEWORKS/include/core",
      "$HDF_FRAMEWORKS/include/utils",
      "$HDF_FRAMEWORKS/utils/include",
      "$HDF_FRAMEWORKS/include/osal",
      "//third_party/bounds_checking_function/include",
      "$HDF_ADAPTER/uhdf/posix/include",
      "$HDF_ADAPTER/khdf/linux/osal/include",
      "//base/hiviewdfx/hilog_lite/interfaces/native/innerkits",

    ]
    public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
    deps = [
      "$HDF_ADAPTER/uhdf/manager:hdf_core",
      "$HDF_ADAPTER/uhdf/posix:hdf_posix_osal",
      "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
    ]

    cflags = [
      "-Wall",
      "-Wextra",
      "-Wno-format",
      "-Wno-format-extra-args",
    ]
    output_dir = "$root_out_dir/"

到了这里,关于OpenHarmony中基于HDF框架的驱动开发和使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenHarmony HDF 框架介绍

    OpenHarmony 系统 HDF 驱动框架采用 C 语言面向对象编程模型构建,通过平台解耦、内核解耦,来达到兼容不同内核,统一平台底座的目的,从而帮助开发者实现驱动一次开发,多系统部署到的效果。 为了达成这样一个目标,OpenHarmony 系统 HDF 驱动框架提供了: 操作系统适配层(

    2024年02月17日
    浏览(45)
  • Openharmony - HDF驱动小示例和测试程序

    By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 最近在学习鸿蒙系统,首当其冲是学习HDF,这里有很多文章可以阅读: https://docs.openharmony.cn/pages/v4.0/zh-cn/device-dev/driver/driver-overview-foundation.md/ 但是千言万语,

    2024年02月22日
    浏览(46)
  • OpenHarmony轻量系统开发【5】驱动之GPIO点灯

    摘要 :本文简单介绍如何操作GPIO去点灯 适合群体 :适用于Hi3861开发板,L0轻量系统驱动开发 5.1点灯例程源码 先看最简单得LED灯闪烁操作 源码结构如下: 第一个BUILD.gn文件内容: 第二个BUILD.gn内容: led_demo.c内容: 编译后烧录进去,应该可以看到复位按键旁边的LED灯一直在

    2024年02月07日
    浏览(39)
  • 《HarmonyOS开发 – OpenHarmony开发笔记(基于小型系统)》第4章 OpenHarmony应用开发实例

    开发环境 : 开发系统:Ubuntu 20.04 开发板:Pegasus物联网开发板 MCU:Hi3861 OpenHarmony版本:3.0.1-LTS 1.新建工程及源码 新建目录 在applications/sample/myapp中新建src目录以及myapp.c文件,代码如下所示。 新建编译组织文件 新建applications/sample/myapp/BUILD.gn文件,内容如下所示: static_libr

    2024年02月09日
    浏览(82)
  • openharmony开发最新4.0版本---数据库连接(二)(基于api10,devstudio4.0) 中relationalStore的使用

    如下代码是一个工具类,可以自己导入到自己项目中,在入口文件中初始化即可使用,使用示例放在下节中 import relationalStore from \\\'@ohos.data.relationalStore\\\' import common from \\\'@ohos.app.ability.common\\\'; import { BusinessError } from \\\'@ohos.base\\\'; import { ValuesBucket, ValueType } from \\\'@ohos.data.ValuesBucket\\\'; const

    2024年01月18日
    浏览(50)
  • 【开源三方库】Easyui:基于OpenAtom OpenHarmony ArkUI深度定制的组件框架

    万冬阳 公司:中国科学院软件所 小组:知识体系工作组 Easyui是一套基于ArkTS语言开发的轻量、可靠的移动端组件库,它是对OpenAtom OpenHarmony(以下简称“OpenHarmony”) ArkUI进行深度定制的组件框架。Easyui可扩展性较强,可以基于源码进行二次开发,修改原有组件以及新增部

    2024年02月03日
    浏览(44)
  • OpenHarmony鸿蒙南向开发案例:【智能猫眼(基于3518开发板)】

    样例简介 本Demo是基于Hi3518开发板,使用开源OpenHarmony开发的RTSP协议流媒体应用。达到将Hi3518开发板中摄像头获取的数据通过RTSP协议传输到手机并显示 。 rtsp实现可参考文档:openharmony_1.0.1实现RTSPServer 运行效果 样例原理 如上图所示,手机播放3518摄像头采集的视频数据。 工

    2024年04月28日
    浏览(65)
  • 鸿蒙OpenHarmony【小型系统 编译】(基于Hi3516开发板)

    OpenHarmony支持hb和build.sh两种编译方式。此处介绍hb方式,build.sh脚本编译方式请参考[使用build.sh脚本编译源码]。 进入源码根目录,执行如下命令进行版本编译。 说明:   _name_为产品名称,例如Hi3516DV300、rk3568等。 检查编译结果。编译完成后,log中显示如下: 编译所生成的文

    2024年04月28日
    浏览(60)
  • openHarmony使用Napi开发样例

    代码gitee路径 Napi在开发工程中的指导         1.2.1 cmake引入按照napi处理后的模块生成一个可以让ninja编译的文件配置。         1.2.2 并且要把cmakelist文件引入到当前模块的打包构建文件中。 在这个代码片段中, sizeof(desc) / sizeof(desc[0])  是用来计算  desc  数组中的元素个数

    2024年03月27日
    浏览(48)
  • OpenHarmony开源鸿蒙学习入门 - 基于3.2Release 应用开发环境安装

    基于目前官方master主支,最新文档版本3.2Release,更新应用开发环境安装文档。 一、安装IDE: 1.IDE安装的系统要求 2.IDE下载官网链接 (IDE下载链接) 3.下载完成后进行IDE安装。 【最新的IDE,HarmonyOS和OpenHarmony的IDE已经统一,只是SDK管理分开】 IDE的依赖有 node.js 和 Ohpm。 有两种

    2024年02月15日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包