OpenHarmony Sensor模块HDI架构
Posted 一日丧命散
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenHarmony Sensor模块HDI架构相关的知识,希望对你有一定的参考价值。
目录
├── README.en.md
├── README.md
├── sensor #sensor HDI 接口定义
│ └── v1_0 #sensor HDI 接口 v1.0版本定义
│ ├── BUILD.gn #sensor idl文件编译脚本
│ ├── ISensorCallback.idl #sensor callback 接口定义idl文件
│ ├── ISensorInterface.idl #sensor interface 接口定义idl文件
│ └── SensorTypes.idl #sensor 数据类型定义idl文件
├── audio #audio HDI 接口定义
│ └── ...
├── camera #camera HDI接口定义
├── codec #codec HDI接口定义
├── display #display HDI接口定义
├── format #format HDI接口定义
├── input #input HDI接口定义
├── misc #misc HDI接口定义
├── usb #usb HDI接口定义
└── wlan #wlan HDI接口定义
源码分析
基于上一篇文章《OpenHarmony Sensor 订阅流程详解》,已经可以清晰了解Sensor模块从JS到Framework的代码交互流程,本章主要介绍Sensor Service 通过HDF框架访问驱动的方法。
什么是HDF
HDF框架提供了Service访问驱动层的途径。使得Service能够使用HDF框架提供的接口来访问驱动提供的功能,也能接收到驱动发送过来的回调event。
什么是HDI
HDI(Hardware Device Interface)就是由驱动所定义的的设备驱动接口。
hdi-gen工具
通过使用hdi-gen工具,我们可以将HDI所定义的接口转化为我们所需要的HDF框架代码。
HID原理图
通过hid-gen工具,可以自动生成HDF框架的stub 和 proxy代码,他们之间通过IPC通信。
结合代码展示HDF框架代码
橙红色部分: SensorClient(应用框架的Client端),通过IPC和SensorService通信
黄色部分:SensorService(应用框架的Service端),通过IPC和SensorClient通信
绿色部分:HDF框架代码,这部分代码是hdi-gen工具自动生成的,也是我们本章重点介绍的地方
紫色部分:驱动实现代码,接口和HDI定义的保持一致
SensorService作为驱动的调用者,需要由两个角色:
第一,在驱动功能调用过程中,作为proxy角色,通过IPC请求向驱动层发送消息,申请调用驱动层的功能,所以和HDF interface的Proxy相关联。
第二,在驱动回调过程中,作为stub角色,接收驱动层发送过来的IPC消息,以便继续往上层回调,所以和HDF Callback的stub相关联
虽然上面绿色部分的代码是通过hdi-gen工具自动生成,但是还是需要添加部分代码实现,才能调用到驱动代码。所以SensorImpl中需要调用驱动提供的具体接口。
HDF框架代码实践
1) 添加一个全新的模块,编写HDI的.idl文件
huanghao@ubuntu:~/code/OpenHarmony_master/drivers/interface/test/v1_0$ ls -l
total 16
-rw-rw-r-- 1 huanghao huanghao 262 Apr 7 17:10 BUILD.gn
-rw-rw-r-- 1 huanghao huanghao 135 Apr 7 17:17 ITestCallback.idl
-rw-rw-r-- 1 huanghao huanghao 243 Apr 7 17:23 ITestInterface.idl
-rw-rw-r-- 1 huanghao huanghao 224 Apr 7 17:22 TestTypes.idl
----------------------------------Test Types.idl----------------------------------
package test.v1_0;
struct TestEvents
int testValueInt;
unsigned int testValueUnsignedInt;
;
----------------------------------ITestCallback.idl----------------------------------
package test.v1_0;
import test.v1_0.TestTypes;
[callback] interface ITestCallback
OnDataEvent([in] struct TestEvents event);
----------------------------------ITestInterface.idl----------------------------------
package test.v1_0;
import test.v1_0.TestTypes;
import test.v1_0.ITestCallback;
interface ITestInterface
FuncA([in] int testId);
FuncB([in] int testEnumVaule);
FuncRegister([in] int testId, [in] ITestCallback callbackObj);
----------------------------------BUILD.gn----------------------------------
import("//drivers/adapter/uhdf2/hdi.gni") #编译idl必须导入的模板
hdi("test") #目标名称,会生成两个so,分别对应libtest_client_v1.0.z.so和libtest_stub_v1.0.z.so
module_name = "test_service" #module_name控制driver文件中驱动描述符的moduleName
sources = [ #参与编译的idl文件
"ITestCallback.idl", #用于回调的idl
"ITestInterface.idl", #接口idl
"TestTypes.idl", #自定义类型idl
]
language = "cpp" #控制idl生成c或者c++代码,可以选择‘c’ 或者‘cpp’
subsystem_name = "hdf"
part_name = "test_device_driver"
2) 使用hid-gen工具生成HDF代码
需要用到hdi-gen命令,首先把该工具拷贝到 ~/bin/,之后就可以不添加路径,直接使用
cp ./out/rk3568/obj/drivers/framework/tools/hdi-gen/hdi-gen ~/bin/
在test上一层目录执行命令:
通过 -d 参数 将生成代码到指定目录./test_out
code/OpenHarmony_master/drivers/interface$ hdi-gen -c ./test/v1_0/ITestInterface.idl --gen-cpp -d ./test_out
查看代码内容:
test_types.h
Itest_interface.h
工具为我们生成的实现类 test_interface_service.h,内部都是空实现,这个代码只是提供一个架子,内部实现需要自己来写
test_interface_service.cpp
3)在 test_interface_service.cpp中添加代码实现,即可实现驱动层代码调用。
test_interface_service.h
test_interface_service.cpp
经过上面的操作之后,再将Service和HDF层的TestInterfaceProxy相关联,Service和HDF层的TestCallbackStub相关联,就可以实现Service到驱动层代码的调用了。
在官方的HDI使用指导中有个图非常好:
idl文件通过集成编译固定生成libfoo_proxy.z.so和libfoo_stub.z.so。
由hdi-gen工具生成的foo_driver.cpp、foo_service.h、foo_service.cpp、foo_callback_service.h、foo_callback_service.cpp不会参与编译,仅供开发者参考,开发者可手动编写所需的源文件并编译为libfoo_driver.so、libfoo_service.z.so、libfoo_callback_service.z.so。
以上是关于OpenHarmony Sensor模块HDI架构的主要内容,如果未能解决你的问题,请参考以下文章