当前位置: 首页 > news >正文

三、驱动篇-HDF驱动介绍1

一、HDF驱动框架介绍

https://developer.huawei.com/consumer/cn/blog/topic/03651206763670022

HarmonyOS驱动框架采用C语言面向对象编程模型构建,通过平台解耦、内核解耦,来达到兼容不同内核,统一平台底座的目的,从而帮助开发者实现驱动的“一次开发,多系统部署”。

我们可以看到下面3个关键点信息:

  • C语言面向对象编程
  • 平台解耦
  • 内核解耦

1.1 C面向对象编程

https://www.cnblogs.com/lihuidashen/p/13223429.html

1.2 平台解耦

目录 作用
device\soc\rockchip\rk3568 rk3568 芯片的平台驱动实现代码
drivers\hdf_core\framework\support\platform 与平台驱动的统一适配、抽象和管理相关的实现代码
drivers\hdf_core\framework\include\platform 抽象出来的接口声明,供驱动框架中的其他驱动模块使用

1.3 内核解耦

OpenHarmony驱动框架引入了OSAL(Operating system Abstraction Layer,操作系统抽象层),OSAL 只为驱动框架提供了内核部分能力的抽象接口,而隐藏了接口在不同内核中的实现细节。驱动程序完全不需要知道(也不会知道)自己运行在什么内核之上。

鸿蒙4.0

目录 作用
drivers/hdf_core/adapter/khdf/liteos_m OSAL 适配 LiteOS_M内核的实现细节
drivers/hdf_core/adapter/khdf/liteos OSAL 适配 LiteOS_A内核的实现细节
drivers/adapter/khdf/linux OSAL适配Linux内核的实现细节
drivers/hdf_core/interfaces/inner_api/osal OSAL供驱动框架使用的统一抽象接口声明

二、HDF整体驱动框架

鸿蒙驱动架构采用分层解耦设计,每层聚焦特定职责,降低模块间依赖。整体分为以下层级(自底向上):

  1. Hardware(硬件层)
  • 是物理设备的“载体”,分为两类:
    • Board Support Chips(板级支持芯片):主板集成的基础通信接口芯片(如I2C、SPI、GPIO、SDIO),是设备与主板通信的“桥梁”。
    • Peripheral Support Chips(外设支持芯片):外接功能硬件(如TP触摸、LCD屏幕、Sensor传感器、SDIO设备),提供具体业务能力。

2. Support(支撑层)

承上启下,为上层驱动和内核提供硬件适配系统基础服务,分为两类子模块:

  • Platform(平台驱动):对接Hardware的通信协议(I2C、SPI、GPIO、SDIO等),实现“硬件寄存器操作→标准化驱动接口”的转换,是硬件的“直接驱动层”。
  • OSAL(操作系统抽象层):屏蔽不同内核(如Linux、鸿蒙微内核)的差异,提供通用基础服务(Mutex互斥锁、Thread线程、Mem内存、Time时间等),让上层模块“一次开发,多内核适配”。

3. Kernel(内核空间)

是驱动的“核心管理层”,负责设备建模、生命周期管理、资源调度,又细分为多个功能块:

  • Model(设备模型):图中仅示例“Network”,代表特定设备的抽象模型(如网络设备、音频设备等),定义设备的通用行为规范。
  • Host(设备主机管理):聚焦“单设备实例”的管理,包含:
    • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Driver</font>:驱动核心逻辑,<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">DeviceService</font>对外提供设备能力,<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Private data</font>存储设备私有配置;
    • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">hostService</font>:设备服务的“中枢”,<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Observer</font>监听设备状态(如插入、故障),<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Device/DeviceNode/DeviceObject</font>是设备的“对象化封装”(<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">DeviceObject</font>是核心,包含设备属性、操作方法;<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">DeviceNode</font>是设备在系统中的唯一标识;<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Device</font>是实例化载体);
    • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Loader</font>:驱动加载器(加载/卸载驱动),<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Resource Manager</font>:设备资源分配器(如IO地址、中断号)。
  • Manager(全局设备管理):聚焦“多设备全局管控”,是系统级的设备调度中心,包含:
    • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">DeviceManageService</font>:设备管理服务“大管家”,统筹所有设备的生命周期;
    • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Device Host Client</font>:与<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Host</font>模块通信的客户端(跨模块交互),<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">DeviceTokenClnt</font>:设备令牌客户端(处理权限/安全);
    • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Launcher</font>:设备服务启动器,<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Attribute Manager</font>:设备属性管理器;
    • 辅助管理模块:<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">DeviceServiceManage</font>(设备服务管理)、<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Fault Recovery</font>(故障恢复)、<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Security Manager</font>(安全策略)、<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Power Manager</font>(电源功耗)、<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">PNP Manager</font>(即插即用,处理热插拔)。
  • VFS(虚拟文件系统):内核的“文件系统抽象层”,让所有设备能以文件/节点的形式被访问(如<font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">/dev</font><font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">/sys</font>下的设备节点),是用户空间与内核驱动交互的“通用入口”。

4. Userspace(用户空间)

是应用/服务与内核驱动交互的“接口层”,包含:

  • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">HDI(Hardware Driver Interface)</font>:硬件驱动接口规范,定义用户空间与内核驱动的通信协议(如数据格式、调用流程),实现“用户态→内核态”的解耦。
  • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">IO-Dispatcher</font>:IO请求调度器,管理用户空间发起的IO操作(如读写设备),负责请求的排队、分发、结果回调。

5. Tool(工具链)

辅助开发者高效实现驱动,包含:

  • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">HDI-GEN</font>:HDI代码生成工具,根据接口定义自动生成“用户态-内核态”的通信框架代码,减少重复开发。
  • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">Driver Module Template</font>:驱动模块模板,提供标准化的驱动工程结构(如初始化、销毁、IO处理函数),降低入门门槛。
  • <font style="color:rgba(0, 0, 0, 0.88);background-color:rgba(175, 184, 193, 0.2);">HCS-GEN</font>:HCS(Hardware Configuration System,硬件配置系统)代码生成工具,自动将硬件配置文件(如设备地址、中断号)转为驱动可直接读取的代码,实现“配置与逻辑分离”。

三、HDF框架子系统概述

要开发驱动程序,首先要了解HDF定义的 设备驱动模型 ,如下图所示。HDF定义了一种组件化的设备驱动模型,可以为开发者提供更精细化的 设备驱动管理 ,让 设备驱动的开发和部署 更加规范。

介绍HDF框架常用的概念

(1)Host:按照HDF的要求,一般将类型相同、功能相似或业务关联紧密的多种设备放到一个 Host(设备集合) 里面。Host 本身有两种属性,如下表所示:

属性 取值 描述
hostName 字符串 表示宿主的名字。在不同的宿主内需要配置不同的宿主名字,在驱动框的代码中可以通过GetHostNode(const char *inHostName) 来获取匹配指定宿主名字的宿主节点。
priority 整数,0~200(默认为100) 设备集合的优先级。数值越大,优先级越低;如果优先级相同,则不能保证加载顺序。在驱动框架启动宿主时,会通过HdfAttributeManagerGetHostList() 获取到一个按priority 的值由高到低排序的宿主链表( hostList ),据此链表依次启动宿主。

(2)Device(设备):本身没有属性,表示具体某一小类的设备节点的集合,比如 UART 类的 device_uart 作为一个小类别,在其下会有若干个基本类似的具体的 deviceNode ,但每个 deviceNode 可能有不同的驱动服务和私有配置信息,以实现差异化的功能。

(3)Device Node(设备节点):每一个Device Node(设备节点)都有对应(多对一、一对一)的Driver(驱动程序)。HDF驱动框架给设备节点定义的属性如下表所示:

属性 取值 描述
moduleName 字符串 表示驱动的名称。它必须和驱动入口结构 struct HdfDriverEntry 中的 moduleName 的配置一致,这是驱动框架通过设备配置信息(即当前deviceNode 的配置信息)找到匹配的设备驱动程序入口的凭证。
preload 整数 具体定义在:drivers/hdf_core/interfaces/inner_api/host/shared/hdf_device_
desc.h中
驱动被HDF加载的方式。
0:系统会在驱动框架的启动过程中默认加载当前deviceNode 的设备驱动程序
1:系统支持快速启动功能时,则会在系统完成驱动框架的启动之后再加载 preload 配置为1的deviceNode 的设备驱动程序,如果系统不支持快速启动功能,则其含义与 preload 配置为 0 的含义相同
2:系统在驱动框架的启动过程中默认不加载当前 deviceNode 的设备驱动程序,而是在用户态程序尝试绑定该驱动服务时,如果发现设备驱动服务节点不存在,驱动框架就会尝试动态加载该设备驱动
priority 整数,0~200 驱动的优先级。数值越大,优先级越低;如果优先级相同,则不能保证加载顺序。
serviceName 字符串 表示驱动对外发布服务的名字,该服务名字必须全局唯一,上层应用通过该名字可以找到并绑定设备驱动提供的服务。
policy 整数 驱动对外发布服务的策略。
permission 整数 表示驱动创建的设备服务节点的权限。该字段仅在驱动服务对用户态发布服务时(即 po1icy为 2)才有效,其值使用 UNIX 文件权限的八进制数字模式来表示,长度为4位,例如0644。开发者应当保证驱动服务的发布策略与设备服务节点的权限相互匹配,否则可能会导致无法访问驱动服务或设备服务节点的权限被放大
deviceMatchAttr 字符串 用于匹配当前 deviceNode 的私有配置信息的关键字。如果当前 deviceNode 没有私有配置信息,则这个字段不需要填写;反之,则该字段必须和驱动私有配置信息的对应节点的 match_attr 字段的值匹配。这是当前deviceNode 的驱动程序找到对应的私有配置信息的凭证。

OpenHarmony 驱动框架以hcs(HDF Configuration Source,HCS)文件的形式组织源代码,以键值(Key-Value)对的形式对设备驱动信息进行配置和记录,从而实现驱动配置信息与驱动实现代码的解耦。hcs文件的源代码被hc-gen(HDF Configuration Generator,HC-GEN)工具编译成hcb(HDF Configuration Binary,HCB)二进制文件然后打包成 .o 文件链接进内核镜像中,然后在驱动框架启动阶段被 hcs-parser 工具加载和分析,还原成以g_hcsTreeRoot 为根节点的树状结构,最终被驱动框架各模块所使用。

所有的hcs文件可以简单地分成3类:

  1. 编译入口文件 hdf.hcs;

  2. 设备节点描述文件 device_info.hcs;

  3. 驱动私有的配置信息描述文件xxx_config.hcs。

1 hdf.hcs

在编译脚本Makefile中指定的编译hcs源文件的入口一般名为 hdf.hcs,

2 device_info.hcs - 驱动设备描述(必选)

作用:负责描述设备的整体结构和驱动的基本信息,用来描述设备结构、驱动服务。节点等元信息

描述:名为 device_info.hcs 的文件是专门用来描述设备节点的。在同一个系统中,可以有多个device_info.hcs 文件,它们的结构都一样,hc-gen 工具在编译时会把相同层级的设备节点描述文件归类合并在一起。在 device_info.hcs 文件的 root 节点下是 device_info 子节点。

例如

root {platform {rk3568_sample_config {match_attr = "rk3568_sample_config";   //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致}}
}

3 config.hcs

http://www.lryc.cn/news/609384.html

相关文章:

  • 【Unity】背包系统 + 物品管理窗口 (上)
  • Python 的标准库 bisect 模块
  • 从WebShell 与 ShellCode 免杀技术 打造适合自己的免杀技术链
  • [Oracle] 获取系统当前日期
  • 使用AssemblyAI将音频数据转换成文本
  • [Oracle] TO_DATE()函数
  • gpu instancer crowd 使用自定义材质并且只修改单个物体的材质参数
  • 机器学习 决策树基本介绍
  • [2025ICCV-目标检测方向]DuET:通过无示例任务算术进行双增量对象检测
  • 数据结构:单向链表的函数创建
  • kubernetes基础知识
  • io_cancel系统调用及示例
  • 11.消息队列
  • IDEA查看源码利器XCodeMap插件
  • LangChain4J入门:使用SpringBoot-start
  • 网络规划与设计5个阶段内容
  • 项目日记---高并发内存池整体框架
  • Python中的sys.path与PYTHONPATH全解析:模块导入路径的底层机制与最佳实践
  • 进阶向:YOLOv11模型轻量化
  • 微店所有店铺内的商品数据API接口
  • AI Competitor Intelligence Agent Team
  • io_getevents 和 io_pgetevents 系统调用及示例
  • 【Mysql】日志--错误日志、二进制日志、查询日志、慢查询日志
  • Linux进程启动后,监听端口几分钟后消失之问题分析
  • RocksDb 是什么?levelDB、LSM 树、SSTable又分别是什么?区别呢?
  • Java,八股,cv,算法——双非研0四修之路day24
  • 2025年测绘程序设计比赛--基于统计滤波的点云去噪(已获国特)
  • 【AI】文档理解
  • 旧笔记本电脑如何安装飞牛OS
  • 嵌入式学习日志——数据结构(一)