OpenHarmony系统HDF驱动开发介绍(补充)

发布于:2025-05-15 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、HDF驱动简介

HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。
简单来说:HDF框架的驱动和Linux的驱动比较相似都是由配置文件和驱动源码组成。
HDF驱动:配置文件HCS + 驱动源码。
Linux驱动:配置文件DTS + 驱动源码。

二、HCS文件简介

HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。HC-GEN(HDF Configuration Generator)是HCS配置转换工具,可以将HDF配置文件转换为软件可读取的文件格式:

在弱性能环境中,转换为配置树源码或配置树宏定义,驱动可直接调用C代码或宏式APIs获取配置。
在高性能环境中,转换为HCB(HDF Configuration Binary)二进制文件,驱动可使用HDF框架提供的配置解析接口获取配置。

HCS文件示例:

root {
    device_info {
        match_attr = "hdf_manager";
        template host {
            hostName = "";
            priority = 100;
            template device {
                template deviceNode {
                    policy = 0;
                    priority = 100;
                    preload = 0;
                    permission = 0664;
                    moduleName = "";
                    serviceName = "";
                    deviceMatchAttr = "";
                }
            }
        }
        base :: host {
            hostName = "base_host";
            priority = 50;
            device_support :: device {
                device0 :: deviceNode {
                    policy = 2;
                    priority = 10;
                    permission = 0644;
                    moduleName = "HDF_KEVENT";
                    serviceName = "hdf_kevent";
                }
            }
        }
    }
}

上面是我从一个HCS文件中截取了一点内容,HCS子定义了一套格式。

三、HCS语法说明

下面是从官网的一个截图:
官方介绍

HCS经过HC-GEN编译生成HCB文件,HDF驱动框架中的HCS Parser模块会从HCB文件中重建配置树,HDF驱动模块使用HCS Parser提供的配置读取接口获取配置内容。

表3 HCS配置语法保留关键字

|关键字 | 用途 |说明|

关键字 用途 说明
root 配置根节点 -
include 引用其他HCS配置文件 -
delete 删除节点或属性 只能用于操作include导入的配置树
template 定义模板节点 -
match_attr 用于标记节点的匹配查找属性 解析配置时可以使用该属性的值查找到对应节点

HCS主要分为属性(Attribute)和节点(Node)两种结构。
详细语法说明参考:https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md

上面的示例代码中有:moduleName = “HDF_KEVENT”;
这块的 moduleName 和 DTS文件中驱动节点的 compatible 功能相同,用来匹配对应的驱动代码。

上面的示例代码中有:serviceName = “hdf_kevent”;
当驱动匹配成功后最终在/dev路径下面生成的节点名称 “hdf_kevent”。但是是否在/dev下面生成节点信息和policy的属性有关。

只有policy = 2时,在/dev下面才能看到节点信息。

typedef enum {
    /* 驱动不提供服务 */
    SERVICE_POLICY_NONE = 0,
    /* 驱动对内核态发布服务 */
    SERVICE_POLICY_PUBLIC = 1,
    /* 驱动对内核态和用户态都发布服务 */
    SERVICE_POLICY_CAPACITY = 2,
    /* 驱动服务不对外发布服务,但可以被订阅 */
    SERVICE_POLICY_FRIENDLY = 3,
    /* 驱动私有服务不对外发布服务,也不能被订阅 */
    SERVICE_POLICY_PRIVATE = 4,
    /* 错误的服务策略 */
    SERVICE_POLICY_INVALID
} ServicePolicy;

四、驱动代码介绍

驱动实现包含驱动业务代码实现和驱动入口注册,具体写法如下:

  • 驱动业务代码
#include "hdf_device_desc.h"          // HDF框架对驱动开发相关能力接口的头文件
#include "hdf_log.h"                  // HDF框架提供的日志接口头文件

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

// 将驱动对外提供的服务能力接口绑定到HDF框架。
int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
{
    HDF_LOGD("Sample driver bind success");
    return HDF_SUCCESS;
}

// 驱动自身业务初始化的接口
int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{
    HDF_LOGD("Sample driver Init success");
    return HDF_SUCCESS;
}

// 驱动资源释放的接口
void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
{
    HDF_LOGD("Sample driver release success");
    return;
}
  • 驱动入口注册到HDF框架
// 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量。
struct HdfDriverEntry g_sampleDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "HDF_KEVENT",
    .Bind = HdfSampleDriverBind,
    .Init = HdfSampleDriverInit,
    .Release = HdfSampleDriverRelease,
};

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

只要驱动代码中的moduleName配置和HCS文件中moduleName配置内容相同就会执行驱动中的Bind函数,Bind函数执行成功后就会执行Init函数。如果Bind和Init函数有一个执行失败会立刻执行Release函数。

五、其他

今天就介绍到这里,我最近几年一直从事音频开发,主要做Linux、Open Harmony系统的音频开发。做过RK系列、海思和展锐的音频适配,大家有什么问题可以留言咨询。


网站公告

今日签到

点亮在社区的每一天
去签到