赞
踩
Android系统开发中硬件抽象层(HAL),它是一组接口和数据类型的定义,用于描述硬件设备的功能和属性,从而实现硬件和软件的解耦。为了方便使用HAL,Android提供了一种专门的语言,叫做HIDL,它是一种基于IDL(接口定义)的语言,可以用于定义HAL接口和数据类型,并生成不同语言和类型的代码文件,如C++、Java、Android.bp等。
本文将介绍两个与HIDL相关的工具:hidl-gen和hidl2aidl。hidl-gen是一个用于生成HIDL代码文件的工具,它可以根据.hal文件中定义的接口和数据类型生成对应的代理类、存根类、回调类等,并提供接口实现和测试的框架和示例代码。hidl2aidl是一个用于转换HIDL代码文件为.aidl文件的工具,它可以根据.hal文件中定义的接口和数据类型生成对应的.aidl文件,并尽可能保持原有的结构和语义。
本文将学习hidl-gen和hidl2aidl的基本用法、生成的代码文件、实现原理、区别和联系等内容,让我们更好地理解和使用这两个工具。
hidl-gen是一个用于生成HIDL代码文件的工具,它可以根据.hal文件中定义的接口和数据类型生成对应的代理类、存根类、回调类等,并提供接口实现和测试的框架和示例代码。hidl-gen接受以下参数:
- -h: 打印这个菜单。
- -L <language>: 可以选择以下选项:
- check : 解析接口,检查是否有效,但不写入任何文件。
- c++ : (内部) (已弃用) 生成C++接口文件,用于与HIDL接口通信。
- c++-headers : (内部) 生成C++头文件,用于与HIDL接口通信。
- c++-sources : (内部) 生成C++源文件,用于与HIDL接口通信。
- export-header : 根据@export枚举生成一个头文件,用于维护旧代码。
- c++-impl : 生成HIDL接口的C++实现的模板和示例代码(为了方便)。
- c++-impl-headers: c++-impl,但只有头文件。
- c++-impl-sources: c++-impl,但只有源文件。
- c++-adapter : 将一个x.(y+n)接口转换为一个x.y接口的适配器。
- c++-adapter-headers: c++-adapter,但只有辅助头文件。
- c++-adapter-sources: c++-adapter,但只有辅助源文件。
- c++-adapter-main: c++-adapter,但只有适配器二进制源文件。
- java : (内部) 生成Java库,用于在Java中与HIDL接口通信。
- java-impl : 生成HIDL接口的Java实现的模板和示例代码(为了方便)。
- java-constants : (内部) 类似于export-header,但是针对Java(如果存在@export,则-Lmakefile总是创建)。
- vts : (内部) 生成vts proto文件,用于在vtsd中使用。
- makefile : (已移除) 用于为-Ljava和-Ljava-constants生成makefile。
- androidbp : (内部) 生成Soong bp文件,用于-Lc++-headers、-Lc++-sources、-Ljava、-Ljava-constants和-Lc++-adapter。
- androidbp-impl : 生成-Lc++-impl创建的实现的模板bp文件。
- hash : 将接口的哈希值以`current.txt`格式打印到标准输出。
- function-count : 打印包或接口添加的函数总数。
- dependencies : 打印所有依赖类型。
- inheritance-hierarchy: 将继承类型的层次结构作为一个JSON对象打印出来。
- format : 格式化.hal文件
- -O <owner>: 模块的所有者,用于-Landroidbp(-impl)?.
- -o <output path>: 文件输出位置。
- -p <root path>: Android构建根目录,默认为$ANDROID_BUILD_TOP或pwd。
- -R: 如果在-r中没有指定,则不添加默认包根目录。
- -r <package:path root>: 例如,android.hardware:hardware/interfaces.
- -v: 输出详细信息。
- -d <depfile>: depfile写入位置。
FQNAME是.hal文件或包名(以@开头)的完全限定名,格式为PACKAGE(.SUBPACKAGE)*@[0-9]+.[0-9]+(::TYPE)?,用于创建输出。
hidl-gen可以根据hardware/interfaces/can_bus/1.0/ICanBus.hal文件生成不同类型的代码文件,以下是一些常用的命令:
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Lc++-headers \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
.
├── default
│ └── android
│ └── hardware
│ └── can_bus
│ └── 2.0
│ ├── BnHwCanBus.h
│ ├── BpHwCanBus.h
│ ├── BsCanBus.h
│ ├── ICanBus.h
│ └── IHwCanBus.h
└── ICanBus.hal
5 directories, 6 files
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Lc++-sources \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
.
├── default
│ └── android
│ └── hardware
│ └── can_bus
│ └── 2.0
│ ├── CanBusAll.cpp
└── ICanBus.hal
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Lc++-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
.
├── default
│ ├── android
│ │ └── hardware
│ │ └── can_bus
│ │ └── 2.0
│ │ └── CanBusAll.cpp
│ ├── CanBus.cpp
│ └── CanBus.h
└── ICanBus.hal
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Landroidbp \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
.
├── Android.bp
└── ICanBus.hal
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
├── default
│ ├── Android.bp
└── ICanBus.hal
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Ljava \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
├── default
│ ├── ICanBus.java
└── ICanBus.hal
hidl-gen -o hardware/interfaces/can_bus/2.0/default -Ljava-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
├── default
│ ├── CanBus.java
└── ICanBus.hal
hidl-gen
使用基于 LLVM 的 Clang 库来解析 .hal
文件并生成 AST。然后它会遍历这个 AST 并使用相应的代码生成器来产生目标代码。(涉及到的非专业词 我也不是很懂,总之 diao)
hidl-gen简化流程:
如果没有这个工具在源代码下执行m hidl2aidl 编译出来就可以了。
hidl2aidl是一个用于将.hal文件转换为.aidl文件的工具,它可以根据.hal文件中定义的接口和数据类型生成对应的.aidl文件,并尽可能保持原有的结构和语义。hidl2aidl接受以下参数:
- -o <output path>:指定输出目录,用于存放生成的.aidl文件。
- -h: 打印这个菜单。
- -p <root path>:指定Android构建根目录,默认为$ANDROID_BUILD_TOP或pwd。
- -R: 如果在-r中没有指定,则不添加默认包根目录。
- -r <package:path root>:指定依赖包的位置,用于解析.hal文件中的import语句。可以有多个-r参数,每个参数表示一个包和一个位置,用冒号分隔。位置可以是相对路径或绝对路径。例如,android.hardware:hardware/interfaces。
- -v: 输出详细信息。
- -d <depfile>:指定depfile写入位置。
FQNAME是.hal文件或包名(以@开头)的完全限定名,格式为PACKAGE(.SUBPACKAGE)*@[0-9]+.[0-9]+(::TYPE)?,用于转换为.aidl文件。
例如,hidl2aidl可以根据android.hardware.smart_home@2.0包中的所有.hal文件生成.aidl文件,并将其存放在hardware/interfaces/smart_home/2.0/aidl目录下。:
hidl2aidl -o hardware/interfaces/can_bus/2.0/aidl -r android.hardware:hardware/interfaces android.hardware.can_bus@2.0
hardware/interfaces/can_bus/2.0$ tree
.
├── aidl
│ └── android
│ └── hardware
│ └── can_bus2
│ ├── conversion.log
│ └── ICanBus.aidl
hidl2aidl会根据.hal文件中定义的接口和数据类型生成对应的.aidl文件,并尽可能保持原有的结构和语义。例如:
// FIXME: license file if you have one
package android.hardware.can_bus2;
interface ICanBus {
// Adding return type to method instead of out param int fd since there is only one return value.
int dev_openCan(in String canx);
// Adding return type to method instead of out param int ret since there is only one return value.
int dev_closeCan(in int fd);
// Adding return type to method instead of out param int ret since there is only one return value.
int dev_sendCan(in int fd, in long canid, in long eff, in long rtr, in int len,
in int[] data);
// Adding return type to method instead of out param byte[] data since there is only one return value.
byte[] dev_receiveCan(in int fd);
}
如果复杂一点的hal文件 生成出来的就很离谱 ,我最开始是手写的,发现像复杂的内容完全写不了一点
hidl2aidl也是一个基于LLVM的工具,利用clang库解析.hal文件,生成AST,并通过AidlCodeGenerator类生成.aidl文件。
hidl2aidl的流程概述:
hidl-gen与hidl2aidl都基于LLVM,使用clang库解析.hal文件生成代码。它们的主要区别是:
它们的共同点是:
文章探讨了两个HIDL工具:hidl-gen和hidl2aidl的基础常用方法。这2个工具都是为了帮助我们使用HIDL定义HAL接口和数据类型。它们根据.hal文件生成标识符,并解析依赖包。自动化生成一些代码框架 。
希望本文能为你使用这两工具提供帮助。如有疑问或建议,请留言。谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。