这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 开源硬件 » 疯壳-鸿蒙OS-HDF驱动框架

共2条 1/1 1 跳转至

疯壳-鸿蒙OS-HDF驱动框架

菜鸟
2021-02-05 14:43:49     打赏

一、简介

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


驱动加载:

HDF驱动加载包括按需加载和按序加载:

1.驱动按需加载

HDF框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载。

2.驱动按序加载

HDF框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。


驱动服务管理:

HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务。


驱动消息机制:

HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息。


二、驱动模型

HDF框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个node,HDF框架管理驱动模型如下图所示:

三、驱动开发实例

接下来几个课程中,我们将手把手带大家进行鸿蒙OS驱动开发,具体内容涉及:

  • 驱动添加

  • 驱动服务管理

  • 驱动消息机制

此外这个过程中还会设计到HCS(HDF驱动框架配置描述)等内容。


本文档接下来的内容会先给大家讲解如何添加驱动。

四、鸿蒙OS驱动添加


A)在源码路径:/home/test/hmos2/vendor/huawei/hdf下创建一个test文件夹,用来保存我们新添的驱动文件,如下:

B)在test文件夹下新建一个sample_driver.c的驱动文件,并编写我们的驱动代码,如下:

Ps:源码具体内容在后文附上!


D)此时驱动文件默认是不参与编译的,接下来我们需要做一下驱动文件编译必要的配置工作:

  • 添加驱动配置信息

驱动配置分为两个部分——HDF框架定义的驱动设备描述和驱动的私有配置信息


驱动设备描述:

HDF框架加载驱动所需要的信息来源于HDF框架定义的驱动设备描述,因此该项是驱动添加的必选项,我

们需要在HDF框架定义的配置文件中添加对应的设备描述,打开源码路径:

vendor/hisi/hi35xx/hi3518ev300/config/device_info/

下的device_info/device_info.hcs文件,新添我们的设备驱动描述信息。

此处设备描述信息添加有两种方式,第一种是新建一个sample_host节点:

sample_host :: host{

hostName = "host0"; // host名称,host节点是用来存放某一类驱动的容器

priority = 100; // host启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证host的加载顺序

device_sample :: device { // sample设备节点

device0 :: deviceNode { // sample驱动的DeviceNode节点

policy = 2; // policy字段是驱动服务发布的策略

priority= 100; // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序

preload = 0; // 驱动按需加载字段

permission = 0664; // 驱动创建设备节点权限

moduleName = "sample_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致

serviceName = "sample_service"; // 驱动对外发布服务的名称,必须唯一

deviceMatchAttr = "sample_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等

}

}

}


添加的结果如下图所示:

另一种方式在原有源码配置plaform节点中添加(此时添加认为新增的驱动跟platform中的设备是同类设备):

            device_sample :: device {

                device0 :: deviceNode {

                    policy = 2;

                    priority = 0;

                    permission = 0644;

                    moduleName = "sample_driver";

                    serviceName = "sample_service";

                    deviceMatchAttr = "sample_driver";

                }

            }

添加的结果如下图所示:

以上内容中驱动服务发布策略policy为2表示驱动对内核态和用户态都发布服务。

priority(取值范围为整数0到200)是用来表示host和驱动的优先级,即驱动按序加载,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。

preload 字段取值为如下的枚举量:

typedef enum {

       DEVICE_PRELOAD_ENABLE = 0,

     DEVICE_PRELOAD_DISABLE,

      DEVICE_PRELOAD_INVALID

} DevicePreload;

配成0(DEVICE_PRELOAD_ENABLE ),则系统启动过程中默认加载;配成1(DEVICE_PRELOAD_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务时,如果驱动服务不存在时,HDF框架会尝试动态加载该驱动。





驱动私有配置信息:

如果驱动有私有配置,则可以添加一个驱动的配置文件,用来填写一些驱动的默认配置信息,HDF框架在加载驱动的时候,该配置非必须项。

在源码路径vendor/hisi/hi35xx/hi3518ev300/config/下新建一个test文件夹,用于存放我们驱动的私有配置文件,新增一个sample_config.hcs,用来配置驱动私有信息:

root{

        sample_version = 1;

        author = "fengke team";

        module = "sample_driver";

        serviceName = "sample_service";

        match_attr = "sample_config"; //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致,见上文配置

}

将该私有配置文件添加到板级配置入口文件hdf.hcs:

驱动编译配置项

驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译,具体可参考驱动文件夹test同级目录下的sample文件中的示例。

在test目录下新增Kconfig文件,如下:

config LOSCFG_DRIVERS_HDF_PLATFORM_SAMPLE

     bool "Enable HDF platform sample driver"

     default n

  depends on LOSCFG_DRIVERS_HDF_PLATFORM

      help

       Answer Y to enable HDF platform sample driver.

在test目录下新增Makefile文件如下:

include $(LITEOSTOPDIR)/config.mk

include $(LITEOSTOPDIR)/../../drivers/hdf/lite/lite.mk

MODULE_NAME := sample_driver

LOCAL_CFLAGS += $(HDF_INCLUDE)

LOCAL_SRCS += sample_driver.c

LOCAL_HCS_SRCS += test/sample_config.hcs

LOCAL_CFLAGS += -fstack-protector-strong

Include  $(HDF_DRIVER)

将上述Kconfig文件添加到test文件夹同级目录下的Kconfig文件中:

修改test文件夹同级目录下的hdf_vendor.mk文件:

Ps: LITEOS_BASELIB += -lsample_driver

LIB_SUBDIRS    += $(VENDOR_HDF_DRIVERS_ROOT)/test



到此我们sample_driver 驱动就已经添加到源码的配置中了,接下来只需编译即可。

下一节课我们将在此基础上,对驱动相关的内容做更深入的探究。

谢谢!

本课程驱动源码如下:


#include "hdf_device_desc.h"  // HDF框架对驱动开放相关能力接口的头文件

#include "hdf_log.h"          // HDF 框架提供的日志接口头文件


#define HDF_LOG_TAG sample_driver   // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签


//驱动服务结构的定义

struct ISampleDriverService {

    struct IDeviceIoService ioService;       // 服务结构的首个成员必须是IDeviceIoService类型的成员

    //以下可添加自定义的驱动的服务接口

};

//驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架

int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) {

    // deviceObject为HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口

    if (deviceObject== NULL) {

        HDF_LOGE("Sample device object is null!");

        return -1;

    }

    static struct ISampleDriverService mysampleDriver;

    deviceObject->service = &mysampleDriver.ioService;

    return 0;

}

// 驱动自身业务初始的接口

int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) {

    return 0;

}

// 驱动资源释放的接口

void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) {

    return;

}

// 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量

struct HdfDriverEntry g_sampleDriverEntry = {

    .moduleVersion = 1,

    .moduleName = "sample_driver",

    .Bind = HdfSampleDriverBind,

    .Init = HdfSampleDriverInit,

    .Release = HdfSampleDriverRelease,

};

// 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。

HDF_INIT(g_sampleDriverEntry);





关键词: 鸿蒙OS 疯壳    

菜鸟
2021-07-06 15:46:47     打赏
2楼

过来学习一下


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]