重新梳理OpenHarmony的HDF
概述
重新梳理下OpenHarmony下HDF的有关概念及从应用到驱动自上而下的整个流程。
主要包括:
- HDF架构
- HDI接口
- 内核KHDF移植
- 以Light设备为例,看看整个调用流
注:这里讨论的只针对L2标准系统。
HDF架构图
HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路,让驱动开发和部署更加规范,旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的驱动管理的开发环境,力求做到一次开发,多系统部署。
- 驱动加载
HDF驱动框架提供把和配置的设备列表匹配成功的驱动程序加载起来的功能 - 驱动服务管理
HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务 - 驱动消息机制
HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息 - 配置管理
HCS是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理
再看看HDF的架构框图:
现在为了快速适配移植,有些较复杂的驱动并未完全地使用HDF框架,还是使用的是Linux的驱动,然后在HAL层做一个连接 adapter层,如之前提过的Audio音频驱动。
HDI接口
HDF 驱动框架的一个重要功能是为系统提供稳定的统一的硬件接口,这样才能保证系统服务可以运行在不同硬件上而不需要额外的适配工作,HDI(Hardware Device Interfaces)正是为了实现该目的而设计。
HDI 是对硬件功能的较高层次抽象接口,各类外设完成 HDI 接口定义后便只会在 HDI 的兼容性规则下进行变更,从而保证接口的稳定性。具体的驱动实现不需要再重复定义 HDI 接口,只需要按需实现即可接入系统功能。
在不同量级的 OpenHarmony 系统上,HDI 存在两种部署形态,IPC 模式和直通模式。
在轻量级 OpenHarmony 系统上,出于减小系统性能负载考虑,HDI 实现为用户态共享库,由系统服务直接加载 HDI 实现到自己进程中函数调用使用。HDI 实现封装具体的用户态内核态交互过程,当需要访问驱动程序时使用 IO Service 请求将消息通过 system call 方式调用到内核驱动实现。
在标准 OpenHarmony 系统上,HDI 以独立服务进程方式部署,系统服务只加载 HDI 客户端实现到自己进程中,实际业务运行在独立进程中,客户端通过 IPC 与服务端交互,便于架构解耦、权限管理。
内核KHDF移植
下面是官方提供的一种快速移植OpenHarmony Linux内核的方法:
从上面可以看出,OpenHarmony 内核态层其实能够由两种方法得到:
方法一: OH 内核态层 = 三方Linux内核 + OH内核态基础代码 + OH内核态特性(可选特性或者必选特性,如必选特性HDF,今后的可选特性HMDFS等)
也就是直接借助三方Linux内核,再加上基础OH内核态基础代码、以及HDF等OH内核态特性。
方法二: OH 内核态层 = OH Linux内核 + OH内核态特性(可选特性或者必选特性,如必选特性HDF,今后的可选特性HMDFS等)
也就是直接采用OHLinux内核,然后再加入OH的其他内核态特性。
所以整个移植流程可以分为三步:
- 准备整体构建环境,包括将三方芯片平台的现有内核代码拷贝到OpenHarmony的整体编译环境下。
- OpenHarmony内核态基础代码的移植。
- OpenHarmony内核态必选特性(如HDF等)的移植。
OpenHarmony内核态基础代码主要是轻量化内核日志服务相关,如hilog
, hievent
等。
移植内核态必选特性HDF移植主要是通过打HDF补丁,官方有提供一个patch_hdf.sh
脚本。
具体的步骤及细节就不再详细介绍了,可看官方文档。
Light设备从上到下整个调用流程
以一个简单的且完全基于HDF的驱动模型(Light)来看整个调用流
light_interface_native
Light Agent:
对应用提供API接口(native interface)base/sensors/miscdevice/interfaces/native/light/src/light_agent.cpp
liblight_native
Light Client:
上层Light是属于Miscdevice(还有包括vibrator)的,这里Light Client会调用Miscdevic Proxy的相关接口。base/sensors/miscdevice/frameworks/native/miscdevice/src/light_client.cpp
Miscdevice Service Proxy:
Proxy是接口IPC模型生成的代理类,最终会调用 remote->SendRequest
,来实现IPC通信。base/sensors/miscdevice/frameworks/native/miscdevice/src/miscdevice_service_proxy.cpp
libmiscdevice_service
Miscdevice Service Stub:
Proxy是接口IPC模型生成的桩类,通过 OnRemoteRequest
来响应Proxy代理类的请求。base/sensors/miscdevice/services/miscdevice_service/src/miscdevice_service_stub.cpp
Miscdevice Service:
继承于上面的Stub桩类,并实现对下面HDI接口的调用base/sensors/miscdevice/services/miscdevice_service/src/miscdevice_service.cpp
Miscdevice Service HDI:
Miscdevice Service相关HDI接口处理base/sensors/miscdevice/services/miscdevice_service/hdi_connection/interface/src/light_hdi_connection.cpp
base/sensors/miscdevice/services/miscdevice_service/hdi_connection/adpter/src/hdi_light_connection.cpp
UHDF驱动
hdi service:
向下调用Light Controller,HDI接口的真正实现drivers/peripheral/light/hdi_service/light_interface_impl.cpp
用于发布 IoService 服务,IoService 设备服务即为 HDI 服务实体,实现方式与 KHDF 驱动类似。drivers/peripheral/light/hdi_service/light_interface_driver.cpp
Light Controller(HAL):
向上对接Light的hdi service,向下对接Light的KHDF驱动,通过IO Service的Dispatch接口调用内核态驱动。drivers/peripheral/light/hal/src/light_controller.c
KHDF驱动
Light Driver:
Light的KHDF驱动,Light控制的具体实现,通过调用Osal接口及平台驱动的GPIO相关接口(WriteGpio
等),实现对Light的硬件控制。drivers/hdf_core/framework/model/misc/light/driver/src/light_driver.c