鸿蒙OpenHarmony HDF 驱动开发

目录

最近忙于适配OpenHarmonyOS LiteOS-M 平台,已经成功实践适配平台GD32F407、STM32F407、STM32G474板卡,LiteOS适配已经算是有实际经验了。

但是,鸿蒙代码学习进度慢下来了。还是得不断学习理论知识丰富自己的认知。接下来时间要把HDF驱动框架熟悉,完善南向开发技术点。

一、概述

HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路,让驱动开发和部署更加规范,旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的驱动管理的开发环境,力求做到一次开发,多系统部署。

HDF支持两种加载方式:

  • 按需加载, HDF框架支持驱动在系统后动过程中默认加载,或者在系统后动之后动态加载。
  • 按序加载, HDF框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。

驱动开发步骤:

  1. 驱动程序实现,包含驱动业务代码和驱动入口注册到HDF框架。
  2. 驱动编译,将业务代码进行编译,同时将结果编译进内核。
  3. 驱动配置,HDF使用HCS作为配置描述源码驱动配置包含两部分HDF框架定义的驱动设备描述和驱动的私有配置信息。

二、HDF驱动框架

HDF驱动框架主要包含三部分:

  • 1、驱动程序部分----完成驱动的功能逻辑。
  • 2、驱动配置信息----指示驱动的加载信息内容。
  • 3、驱动资源配置----配置驱动的硬件配置信息。

三、驱动程序

驱动程序主要是完成驱动功能的逻辑代码,轻量内核LiteOS-M驱动程序代码路径为:drivers/hdf_core/adapter/platform 。

SDK源码使用drivers/hdf_core/adapter/platform目录,放置适配LiteOS-M各个平台驱动程序。

c 复制代码
drivers/hdf_core/adapter/platform
├── BUILD.gn
├── can
├── gpio
├── i2c
├── mipi_dsi
├── pwm
├── spi
├── uart
└── watchdog

这里以LiteOS-M GPIO HDF驱动为例,对于开发者首先看到的是驱动入口部分,驱动入口通过结构体DriverEntry进行描述。其中主要包含Bind, Init 和Release三个接口。

c 复制代码
/* HdfDriverEntry definitions */
//struct HdfDriverEntry定义在:drivers/hdf_core/interfaces/inner_api/host/shared/hdf_device_desc.h
struct HdfDriverEntry g_GpioDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "ST_GPIO_MODULE_HDF", // 职责:与hdf hcs结点moduleName进行匹配
    .Bind = GpioDriverBind,             // 职责:绑定驱动对外提供的服务接口到HDF
    .Init = GpioDriverInit,             // 职责:初始化驱动自身的业务
    .Release = GpioDriverRelease,       // 职责:释放驱动资源,发生异常时也会调用
};
HDF_INIT(g_GpioDriverEntry);            //注册到HDF框架中

Bind接口描述:该接口的作用主要是完成驱动设备和设备服务接口的bind动作。

c 复制代码
static int32_t GpioDriverBind(struct HdfDeviceObject *device)
{
    if (device == NULL) {
        HDF_LOGE("device object is NULL\n");
        return HDF_FAILURE;
    }

    return HDF_SUCCESS;
}

Init接口描述:当框架完成设备绑定动作后,就开始调用驱动初始化接口,初始化成功后,驱动框架根据配置文件决定是对外创建设备服务接口,还是接口只对当前服务可见。如果Init初始化失败,驱动框架就会主动释放创建的设备接口等信息。

c 复制代码
static int32_t GpioDriverInit(struct HdfDeviceObject *device)
{
    int32_t ret;
    struct GpioCntlr *gpioCntlr = NULL;

    if (device == NULL) {
        HDF_LOGE("%s: device is NULL", __func__);
        return HDF_ERR_INVALID_PARAM;
    }

    ret = PlatformDeviceBind(&g_stmGpioCntlr.device, device);   //绑定设备对象
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: bind hdf device failed:%d", __func__, ret);
        return ret;
    }

    gpioCntlr = GpioCntlrFromHdfDev(device);                    //获取gpio控制器
    if (gpioCntlr == NULL) {
        HDF_LOGE("GpioCntlrFromHdfDev fail\r\n");
        return HDF_DEV_ERR_NO_DEVICE_SERVICE;
    }

    ret = AttachGpioDevice(gpioCntlr, device);                  /* GpioCntlr add GpioDevice to priv */
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("AttachGpioDevice fail\r\n");
        return HDF_DEV_ERR_ATTACHDEV_FAIL;
    }

    gpioCntlr->ops = &g_GpioCntlrMethod;                        /* 绑定控制器控制方法 */
    ret = GpioCntlrAdd(gpioCntlr);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("GpioCntlrAdd fail %d\r\n", gpioCntlr->start);
        return HDF_FAILURE;
    }

    return HDF_SUCCESS;
}

gpio控制器方法实现。

c 复制代码
/* GpioMethod definitions */
struct GpioMethod g_GpioCntlrMethod = {
    .request = NULL,
    .release = NULL,
    .write = GpioDevWrite,
    .read = GpioDevRead,
    .setDir = GpioDevSetDir,
    .getDir = GpioDevGetDir,
    .toIrq = NULL,
    .setIrq = GpioDevSetIrq,
    .unsetIrq = GpioDevUnSetIrq,
    .enableIrq = GpioDevEnableIrq,
    .disableIrq = GpioDevDisableIrq,
};

Release接口描述:当用户需要卸载驱动时,驱动框架先通过该接口通知驱动程序释放资源,然后再释放其他内部资源。

c 复制代码
static void GpioDriverRelease(struct HdfDeviceObject *device)
{
    struct GpioCntlr *gpioCntlr = NULL;

    if (device == NULL) {
        HDF_LOGE("%s: device is NULL", __func__);
        return;
    }

    gpioCntlr = GpioCntlrFromHdfDev(device);
    if (gpioCntlr == NULL) {
        HDF_LOGE("%s: host is NULL", __func__);
        return;
    }

    gpioCntlr->count = 0;
}

四、驱动配置

HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。

驱动配置包含两部分,HDF框架定义的驱动设备描述和驱动的私有配置信息。

设备描述信息

HDF框架加载驱动所需要的信息来源于HDF框架定义的驱动设备描述,因此基于HDF框架开发的驱动必须要在HDF框架定义的device_info.hcs配置文件中添加对应的设备描述。

待续...

坚持就有收获

相关推荐
华普微HOPERF2 小时前
数字隔离器,新能源汽车PTC中的“电气安全卫士”
科技·物联网·汽车
敲代码的鱼哇3 小时前
跳转原生系统设置插件 支持安卓/iOS/鸿蒙UTS组件
android·ios·harmonyos
在下历飞雨3 小时前
Kuikly基础之状态管理与数据绑定:让“孤寡”计数器动起来
ios·harmonyos
在下历飞雨3 小时前
Kuikly基础之Kuikly DSL基础组件实战:构建青蛙主界面
ios·harmonyos
HarmonyOS小助手5 小时前
HEIF:更高质量、更小体积,开启 HarmonyOS 图像新体验
harmonyos·鸿蒙·鸿蒙生态
嘿嘿-g6 小时前
华为IP(9)
网络·华为
self_myth6 小时前
[特殊字符] 深入理解操作系统核心特性:从并发到分布式,从单核到多核的全面解析
windows·macos·wpf·harmonyos
糖糖单片机设计8 小时前
硬件开发_基于物联网的老人跌倒监测报警系统
stm32·单片机·嵌入式硬件·物联网·51单片机
TDengine (老段)14 小时前
TDengine 时间函数 WEEKDAY() 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
TDengine (老段)14 小时前
从 ETL 到 Agentic AI:工业数据管理变革与 TDengine IDMP 的治理之道
数据库·数据仓库·人工智能·物联网·时序数据库·etl·tdengine