鸿蒙 HDF 框架介绍

news2024/11/18 13:34:10

鸿蒙 HDF 框架介绍

  • 鸿蒙 HDF 框架介绍
  • HDF 驱动框架框图
  • HDF 驱动框架工作原理
  • HDF 驱动框架工作原理框图:
  • HDF 驱动加载过程分析
    • HDF 驱动加载过程分析——驱动实现1
    • HDF 驱动加载过程分析——驱动实现2
    • HDF 驱动加载过程分析——获取驱动列表
    • HDF 驱动加载过程分析——获取设备列表
    • HDF 驱动加载过程分析——设备与驱动的匹配
    • HDF 驱动加载过程分析——加载过程流程图
    • HDF 驱动加载过程分析——总结
  • 参考资料链接


鸿蒙 HDF 框架介绍

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

为了达成这样一个目标,openharmony 系统 HDF 驱动框架提供了:
操作系统适配层(OSAL):对内核操作系统相关接口进行统一封装,屏蔽不同系统的操作接口;
平台驱动接口:提供 Board 部分驱动(例如:i2c、spi、uart 总线等平台资源)支持,同时对 Board 硬件操作进行统一的适配接口抽象,方便开发者只需要开发新硬件抽象接口,即可获得新增 Board 部分驱动支持
驱动模型:面向器件驱动,提供常见的驱动抽象模型,主要打成两个目的:
提供标准化的器件驱动模型,开发者无需独立开发,通过配置即可完成驱动部署
提供驱动模型抽象,屏蔽驱动与不同系统组件之间的交互,使得驱动更具备通用性。

openharmony 系统 HDF 驱动框架主要由:

  • 驱动基础框架
  • 驱动程序
  • 驱动配置文件
  • 驱动接口

这四部分组成。

  1. HDF 驱动基础框架提供统一的硬件资源管理,驱动加载管理以及设备节点管理等功能。驱动框架采用的是主从模式设置,由 device manager 和 device host 组成。device manager 提供了统一的驱动管理,device manager 启动时根据 device information 提供驱动设备信息加载相应的驱动 device host,并控制 host 完成驱动的加载。 device host 提供驱动运行的环境,同时预置 host framework 与 device manager 进行协同,完成驱动加载和调用。根据业务的需求 device host 可以有多个实例。
  2. 驱动程序实现驱动具体的功能,每个驱动由一个或者多个驱动程序组成,每个驱动程序都对应着一个 driver entry。driver entry 主要完成驱动的初始化和驱动接口绑定功能;
  3. 驱动配置文件(.hcs),主要由设备信息(device information)和设备资源(device resource)组成,device information 完成设备信息的配置(如配置接口发布策略,驱动加载方式等)。device resource 完成设备资源的配置(如 GPIO 管脚、寄存器等资源信息配置等);
  4. 驱动接口(HDI),提供标准化的接口定义和实现,驱动框架提供 IO services 和 IO dispatcher 机制,是的不同部署形态下驱动接口趋于形式一致。

在这里插入图片描述

HDF 驱动框架框图

HDF 框架将一类设备驱动放在同一个 host 里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个 node, HDF 框架管理驱动模型如下图所示:

在这里插入图片描述

HDF 驱动框架工作原理

device manager 提供了统一的驱动加载管理机制和驱动接口发布机制。
当 device host 环境加载完成时,device manager 根据 device information 信息,请求 host 加载相应的驱动程序,device host 在收到请求时,进行以下操作:

  • 根据请求加载设备信息,查找并加载指定路径下驱动镜像或从指定段地址(section)查找驱动程序入口
  • 查找驱动设备描述符,匹配对应的设备驱动
  • 当驱动匹配成功时,加载指定驱动程序镜像
  • host framework 在驱动程序镜像加载成功后,调用驱动程序(driver entry)的绑定接口和初始化接口,实现与驱动程序的服务对象绑定,同时初始化设备驱动程序
  • 当 device information 配置中的服务策略要求对外暴露驱动接口时,驱动框架就将驱动程序的服务对象添加到对外发布的服务对象列表中,外部客户端程序就可以通过此列表来查询并访问相应的服务接口。

HDF 驱动框架工作原理框图:

在这里插入图片描述

HDF 驱动加载过程分析

openharmony 系统驱动根据驱动程序部署的不同方式,存在两种驱动加载方式:

  • 动态加载方式:采用传统的 so(共享库)加载方式,驱动程序通过指定 symbol 方式找到驱动函数入口进行加载
  • 静态加载方式:采用将驱动程序通过 scatter 编译到指定的 section,再通过访问指定 section 对应的地址,找到驱动函数入口进行加载。

下面结合一个 sample 示例代码,讲解驱动加载过程,重点分析静态加载方式下内核态驱动加载过程。

HDF 驱动加载过程分析——驱动实现1

在 HDF 驱动框架中,HdfDriverEntry 对象被用来描述一个驱动实现:

struct HdfDriverEntry{
    int32_t    moduleVersion;
    const char *moduleName;
    int32_t    (*Bind)(struct HdfDeviceObject *deviceObject);
    int32_t    (*Init)(struct HdfDeviceObject *deviceObject);
    void     (*Release)(struct HdfDeviceObject *deviceObject);
}
  • Bind 接口:实现驱动接口实例化绑定,如果需要发布驱动接口,会在驱动加载过程中被调用,实例化该接口的驱动服务并和 deviceobject 绑定;
  • Init 接口:实现驱动的初始化,返回错误将中止驱动加载流程;
  • Release 接口:实现驱动的卸载,在该接口中释放驱动实例的软硬件资源。

HDF 驱动加载过程分析——驱动实现2

int SampleDriverBind(struct HdfDeviceObject *deviceObject)
intSampleDriverInit(struct HdfDeviceObject *deviceObject)
intSampleDriverRelease(struct HdfDeviceObject *deviceObject)

struct HdfDriverEntry g_sampleDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "sample_driver",
    .Bind = SampleDriverBind,
    .Init = SampleDriverInit,
    .Release = SampleDriverRelease
};

HDF_INIT(g_sampleDriverEntry);

将 HDF_INIT 宏展开:

#define HDF_SECTION    __attribute__((section(".hdf.driver")))
#define HDF_DRIVER_INIT(module)    \
const size_t    USED    ATTR    module##HdfEntry HDF SECTION = (size_t)(&(module))

在这里插入图片描述

可以看到 HDF_INIT 宏是定义了一个 “驱动模块名+HdfEntry”的符号放到 “.hdf.driver” 所在的 section,该符号指向的内存地址即为驱动程序入口结构体的地址。这个特殊的 section 将用于开机启动时查找设备驱动。

HDF 驱动加载过程分析——获取驱动列表

在这里插入图片描述

HDF 驱动框架通过将驱动程序入口符号的地址集中存放到一个特殊的 section 来实现对驱动的索引,这个 section 的开头和结尾插入了 _hdf_drivers_start、_hdf_drivers_end 两个特殊符号,用于标记这个 section 的范围,两个特殊符号之间的数据即为驱动实现指针。

HDF 驱动加载过程分析——获取设备列表

在这里插入图片描述

配置文本编译后会变成二进制格式的配置文件,其中设备相关信息被存放在一个用 “hdf_manager” 标记的 device_info 配置块中,host 的内容以块的形式在 device_info 块中依次排列,host 块中记录了 host 名称、启动优先级和设备列表信息。设备信息中的 moduleName 字段将用于和驱动程序入口中的 moduleName 进行匹配,从而为设备匹配到正确的驱动程序。

HDF 驱动加载过程分析——设备与驱动的匹配

在系统启动时,驱动框架先启动(device manager、device host),通过解析配置文件获取到设备列表,通过读取“.hdf.drivers” 段读取到驱动程序列表,然后遍历设备列表与驱动程序列表进行匹配,并加载匹配成功的驱动。驱动框架有两大核心管理者:

  • device manager 负责设备的管理,包括设备加载、卸载和查询等设备相关功能
  • device service manager 负责管理设备发布的接口服务,提供接口服务的发布、查询等功能

驱动加载主要有 device manager 主导,首先 device manager 要解析配置文件中的 host 列表,根据 host 列表中的信息来实例化对应的 host 对象,host 解析文件获取到关联的设备列表,遍历设备列表去获取与之匹配的驱动程序名称,然后基于驱动程序名称遍历前面提到的 hdf.driver section 获取驱动程序地址。

HDF 驱动加载过程分析——加载过程流程图

在这里插入图片描述

device manager 遍历设备列表,当查找到对应驱动时,为设备创建 device 对象实例,如果设备配置中的 policy 字段为需要对外发布的驱动接口,那么驱动的 bind 接口将首先被调用,用于关联设备和服务实例。然后驱动的 Init 接口将被调用,用于完成驱动的相关初始化工作。如果驱动被卸载或者因为硬件等原因 Init 接口返回失败,Release 将被调用,用于释放驱动申请的各种资源。

HDF 驱动加载过程分析——驱动框架启动
驱动框架通过 late_initcall 启动

static init __init DeviceManagerInit(void)
{
    int ret;
    ret = DeviceManagerStart();
    return ret;
}

late_initcall(DeviceManagerInit);

late_initcall 宏展开
在这里插入图片描述

宏含义:

  1. 声明一个类型为 initcall)_t,名称为 __initcall_DeviceManagerInit 的函数指针
  2. 将这个函数指针初始化为 DeviceManagerInit
  3. 编译的时候需要把这个函数指针变量放置到名称为 “.initcall7.init”的 section 中,其实质就是将这个函数DeviceManagerInit的首地址放置到这个“.initcall7.init”的 section 中

在这里插入图片描述

在这里插入图片描述

HDF 驱动加载过程分析——总结

  1. 在系统启动时,devicemanagerInit 通过 late_initcall 先启动
  2. device manager 根据 device information 信息,解析配置文件中的 host 列表,根据 host 列表中的信息来实例化对应的 host 对象
  3. host 变量设备列表去获取与之匹配的驱动程序名称,然后基于驱动程序名称遍历 .hdf.driver section 获取驱动程序地址
  4. 设备与驱动匹配成功后,获取指定驱动的入口地址,加载对应的设备驱动程序
  5. 调用指定驱动的 bind 接口,用于关联设备和服务实例
  6. 调用指定驱动的 init 接口,拥有完成驱动的相关初始化工作
  7. 如果驱动被卸载或者因为硬件等原因 init 接口返回失败,release 将被调用用于释放驱动申请的各类资源。

参考资料链接

  • 鸿蒙官方 doc 文档:https://gitee.com/openharmony/docs#/openharmony/docs/blob/master/zh-cn/readme.md

  • 鸿蒙官网:https://www.openharmony.cn/mainPlay

  • 课程链接:https://growing.openharmony.cn/mainPlay/learnPathMaps?id=49

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

buu刷题记录

[ACTF新生赛2020]crypto-aes from Cryptodome.Cipher import AES import os import gmpy2 from flag import FLAG from Cryptodome.Util.number import *def main():keyos.urandom(2)*16ivos.urandom(16)print(bytes_to_long(key)^bytes_to_long(iv))aesAES.new(key,AES.MODE_…

第五章. 可视化数据分析图表—综合应用(双y轴,堆叠柱形图,颜色渐变饼形图,等高线图)

第五章. 可视化数据分析图 5.7 综合应用 1.双Y轴可视化数据分析图表的实现 (柱形图折线图) 双y轴,顾名思义就是两个y轴,可以通过双y轴看出发展情况的同时,还可以看到正常速度。 1).注意: add_subplot一定要…

【自学Python】Python2代码转Python3代码

Python2代码转Python3代码 Python2代码转Python3代码教程 由于 Python 存在 Python2 和 Python3 两个主要的版本方向,经常会有将 Python2 的代码转到 Python3 的环境下运行的需求。 尤其是跑一些神经网络的代码时有很多是在 Python2 的环境下写的。在 Python3 下…

EXCEL的查找:如何按 行号+列号 进行查询

0 首先用match()等取得行号,列号 如果想根据行号列号,精确查找,另外一个区域的数据,可以用如下方法 INDIRECT("Sheet2!r"&MATCH($C11,Sheet2!$A:$A,0)&"C"&MATCH(D$10,Sheet2!$1:$1,0),FALSE) …

使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus)

vite官网 一:初始化项目 1.需要在创建项目的位置cmd目录下执行 2. npm init vitelatest 回车 npm init vitelatest3.填上自己的项目名称 回车 4.选择vue 回车 5.选择TypeScript回车 6.项目创建完成 或者一步到位通过附加的命令行选项直接指定项目名称和你想要使用的…

网络流量监控为某图书馆系统排忧解难(一)

前言 某学校图书馆信息中心老师反应,用户反馈系统有访问慢的情况,需要通过流量分析系统来了解图书馆系统的运行情况,此报告专门针对图书馆系统的性能数据做了分析。 信息中心已部署NetInside流量分析系统,使用流量分析系统提供实…

PB数据库开发技术(七)-PowerBuilder小型数据库应用系统开发

PowerBuilder小型数据库应用系统开发 实验目的 利用前面学过的知识设计一个“图书馆管理系统”,从而进一步掌握powerbuilder数据库开发的基本步骤和方法。 二.实验步骤 建立数据库“图书管理系统”,向数据库中添加操作员表、借书还书表、图书表以及相应数据

Unity 项目中怎样正确的使用 Lua?

(图源siki学院-狸墨老师) 什么是Lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。可以方便的与c/c进行相互调用。但…

Redis:二、Redis常见命令

2. Redis常见命令 2.1 Redis数据结构介绍 Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样 Redis为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网( http://www.redis.cn/…

【JAVA进阶】常用API

📃个人主页:个人主页 🔥系列专栏:JAVASE基础 目录 1.API概述 2.Object类 3.Objects 4.StringBuilder 5.日期与时间 Date 类 SimpleDateFormat Calendar 6.JDK8新增日期类 1.API概述 什么是API? API(Application Program…

Kettle(二)数据同步、迁移(基础版)

目录 1.配置源数据库A 1.1 文件-->数据库连接 1.2 配置数据库,选择自己的数据库并配置。 1.3 数据库配置可能会报错,原因是缺少数据库驱动 2.配置目标数据库(与源数据库一致) 3.数据迁移(举例) 3.…

IntelliJ IDEA的代码搁置功能

使用场景 当遇到需要临时修改的 bug,但当前正在开发的内容不能删掉,这个时候就需要把当前已经开发的代码另外保存下来(即保存现场),当把 bug 改完后再恢复,来回归之前的开发工作,IntelliJ IDEA…

数据可视化系列-02各类图表的综合使用介绍及实践

文章目录3.各类图表的综合使用介绍及实践3.1了解数据功能图1、可视化中的数据2、基于数据的研究3、数据的可视化组件4、可视化图表的作用、制作流程和类型3.2北极星指标展示1、指标类知识回顾:指标类简介、指标类主要场景2、指标类图表:指标看板、指标趋…

Win11的两个实用技巧系列之更新进度条不动的三种解决方法、重置失败未做更改五种解决方法

目录 Win11更新进度条不动怎么办?Win11更新进度条不动的三种解决方法 方法一: 方法二: 方法三: Win11重置失败未做更改怎么办?Win11重置失败未做更改五种解决方法 方法一、重新启用Windows RE 方法二、使用SFC修复系统文件 方法三、从恢复…

java忽略证书验证(兼容http,https)

概述 日常上传、下载文件时可能有不需要验证证书的场景,比如证书过期、不正确之类的也可以正常的上传下载文件。 Java中使用https协议时,是通过X.509证书进行校验的。 首先我们先了解下什么是X.509证书。 什么是X.509证书 X.509是公钥基础设施&#x…

k8s部署prometheus

k8s部署prometheus 1.下载prometheus文件 cd /soft/src git clone -b release-0.5 --single-branch https://github.com/coreos/kube-prometheus.git2.部署 这里部署之前最好改一下alertmanager-alertmanager.yaml这个文件,将replicas:改成2或者3,当为…

Spark 3.0 - 17 ML PCA 主成分分析理论与实战

目录 一.引言 二.PCA 理论 1.主成分分析定义 2.数学基础 A.数据归一化 B.协方差矩阵计算 C.计算协方差矩阵的特征向量和特征值,以识别主成分 D.构造特征向量矩阵 E.沿着主成分轴重新计算数据 三.PCA 实战 1.数据准备 2.PCA 初始化 3.数据降维 四.总结 …

举一反三-自建zabbix监控php

php-fpm监控需要通过nginx服务。因此需要开启相关配置。 php-fpm如果是yum安装的,那么在/etc/php-fpm.d/www.config中编辑如下选项: pm.status_path /php_status 保存并退出编辑。重启php-fpm服务。 接下来编辑nginx配置项。编辑如下: l…

Linux下cal命令C/C++实现(显示日历信息)

大多数用户自然会将计算机上的日历视为GUI应用程序,或直接从桌面显示的东西。但也可以在Linux中使用cal命令通过命令行终端查看日历。 如果您通常使用Linux上的桌面环境,或者您来自Windows或MacOS操作系统,可能会认为这是一种过于复杂的日历…

RFID技术在固定资产管理中的作用

固定资产因具有数量庞大、分布广、变动频繁等特点造成管理难度较大,一直成为企业管理的一大重点。固定资产管理包括资产的新增、调拨、闲置、报废、维修、盘点等操作,让投入使用到报废退出使用的全过程进行全面的信息化管控。以往固定资产的一直由于管理…