OpenHarmony HDF 框架介绍

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: OpenHarmony HDF 框架介绍

OpenHarmony HDF 框架介绍

OpenHarmony HDF 框架介绍

HDF 驱动框架框图

HDF 驱动框架工作原理

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

HDF 驱动加载过程分析

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

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

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

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

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

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

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

参考资料链接


OpenHarmony 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 机制,是的不同部署形态下驱动接口趋于形式一致。

7ab74546e40f4b2ca477af951fe8fdaf.png

HDF 驱动框架框图

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

221f0eeaed704bf89296a174bcaf8561.png

HDF 驱动框架工作原理

device manager 提供了统一的驱动加载管理机制和驱动接口发布机制。

当 device host 环境加载完成时,device manager 根据 device information 信息,请求 host 加载相应的驱动程序,device host 在收到请求时,进行以下操作:


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

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

d40b874163684e61a659b176bb629460.png

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))

eec5134c4df94a148012483268b9274e.png

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


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

f29145f6f71c4fd68d4e5092f07846f4.png

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


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

0cba69c281914f67858f89a7a2f8c879.png

配置文本编译后会变成二进制格式的配置文件,其中设备相关信息被存放在一个用 “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 驱动加载过程分析——加载过程流程图

4a737266050a4192a8ba8364f7c5b0ca.png

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 宏展开

c2fc15563d4544c2b623f4696eb6465b.png

宏含义:


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

18d2acf3122d44b288ca5041f225ecae.png

b9bcb176080b4b3b9329862eed7de1ec.png

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 将被调用用于释放驱动申请的各类资源。

参考资料链接


相关文章
|
5月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
220 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
7月前
|
编解码 Linux
FFmpeg开发笔记(十)Linux环境给FFmpeg集成vorbis和amr
在Linux环境下,为FFmpeg添加对AAC、MP3、OGG和AMR音频格式的支持,需安装libogg、libvorbis和opencore-amr库。首先,从官方源下载各库的最新源码,如libogg-1.3.5、libvorbis-1.3.7和opencore-amr-0.1.6,然后解压并依次执行`./configure`、`make`和`make install`进行编译安装。接着,在FFmpeg源码目录中,使用`./configure`命令重新配置,并重新编译安装FFmpeg。最后,验证FFmpeg版本信息确认已启用ogg和amr支持。
157 0
FFmpeg开发笔记(十)Linux环境给FFmpeg集成vorbis和amr
|
芯片 SoC
OpenHarmony 标准系统HDF框架之I2C驱动开发
OpenHarmony 标准系统HDF框架之I2C驱动开发
365 0
OpenHarmony 标准系统HDF框架之I2C驱动开发
|
编解码 人工智能 Linux
OpenHarmony 标准系统 HDF 框架音视频驱动开发
OpenHarmony 标准系统 HDF 框架音视频驱动开发
693 0
OpenHarmony 标准系统 HDF 框架音视频驱动开发
|
Java Android开发
RK3399平台开发系列讲解(系统篇)1.17、Camera软件框架(目录介绍)
RK3399平台开发系列讲解(系统篇)1.17、Camera软件框架(目录介绍)
109 0
RK3399平台开发系列讲解(系统篇)1.17、Camera软件框架(目录介绍)
|
JavaScript 开发工具 开发者
openHarmony开发环境搭建
从今天开始正式写openHarmony相关的文章,经过一段时间的沉淀,学习之路漫漫,不断地学习才是王道,熟话说万事开头难,安装软件应该是学习的第一道坎,废话不多说了,看内容了~~
328 0
openHarmony开发环境搭建
|
传感器 API 调度
openHarmony系统简介
今天带大家了解一下openHarmony系统,很多人可能听说过Harmony OS,今天要介绍的openHarmony系统就是Harmony OS的抽象,即基础版的,鸿蒙系统最终要实现的就是脱离安卓系统成为一个独立的系统,目前的环境使得鸿蒙系统仍然需要兼容安卓,故openHarmony诞生了,为了更好的进行过渡,同时也为更好的宣传鸿蒙系统。
911 0
openHarmony系统简介
|
算法 Java 开发工具
openHarmony系统打包应用程序
经过一段时间的学习,打包应用并安装应该是最激动人心的一环了,所以今天带大家完成openHarmony应用的安装,正文即将开始~~
452 0
openHarmony系统打包应用程序
|
编解码 网络协议 Linux
多媒体处理工具 FFmpeg 工具集
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。
已移植到loongarch64的libffi源码目录
已移植到loongarch64的libffi源码目录
67 0