在我们学习Android HAL开发时,可能会遇到一些编译或运行时的错误,这些错误可能会影响探索脚本。为了有效地定位和解决这些错误,需要了解Android HAL的架构、工具和方法。本文将介绍一些我自己在学习Android HAL的调试技巧和常见错误的解决方案,希望能帮助到大家。
网上其他文章从不会告诉你 完整的调试过程, 最多只会告诉你结果 看着简单的内容 等你亲自尝试就知道有多少坑。本文只记录不到一半我遇到的问题,有些不是很通用 我就懒得记录了。
如果有错误 请指正,后面HAL相关的调试和解决方案将更新在此。有任何问题 欢迎咨询~
系列文章:
Android HAL深入探索(1): 架构概述
Android HAL深入探索(2): 传统HAL与文件加解密模拟
Android HAL深入探索(3): HIDL Passthrough模式与串口数据回调模拟
Android HAL深入探索(4): HIDL Binderized模式与CAN数据回调模拟
Android HAL深入探索(5): 调试HAL报错与解决方案
问题1:declares types rather than the expected interface type ‘ICanBus’
当尝试编译一个名为android.hardware.can_bus@1.0
的HAL时,可能会遇到以下错误:
declares types rather than the expected interface type 'ICanBus'
ERROR: Could not parse android.hardware.can_bus@1.0::ICanBus. Aborting.
这个错误意味着我们的.hal
文件中没有正确地定义ICanBus
接口,而是声明了一些类型(如struct
或enum
)。这违反了HIDL语言的语法规则,因为.hal
文件必须以接口定义开始,并且只能有一个接口定义。
简单的说就是hal文件里面必须以interface 开头,不然就会报这个错误。
原因: .hal文件的结构不符合HIDL语法规则
HIDL语言是一种用于定义Android HAL接口的语言,它有一些特定的语法规则和约定。其中之一是.hal
文件必须以接口定义开始,并且只能有一个接口定义。比如 如果想要定义一个名为android.hardware.can_bus@1.0::ICanBus
的接口,.hal
文件应该像这样:
package android.hardware.can_bus@1.0;
interface ICanBus {
// methods and types for the interface
}
如果在接口定义之前或之后声明了一些类型(如struct
或enum
),那么HIDL编译器(hidl-gen
)就会报错,因为它无法解析我们的接口定义。如果我们的.hal
文件像这样:
package android.hardware.can_bus@1.0;
struct CanFrame {
// fields for the struct
}
interface ICanBus {
// methods and types for the interface
}
那么HIDL编译器就会报错:
declares types rather than the expected interface type 'ICanBus'
ERROR: Could not parse android.hardware.can_bus@1.0::ICanBus. Aborting.
解决方案: 重新组织.hal文件或创建新的.hal文件
为了解决这个错误,有两种的方案:
- 重新组织
.hal
文件:将接口定义移到文件的顶部,然后再放其他的类型定义。可以将上面的.hal
文件修改为:
package android.hardware.can_bus@1.0;
interface ICanBus {
// methods and types for the interface
}
struct CanFrame {
// fields for the struct
}
- 创建新的
.hal
文件:如果我们想要将类型定义和接口定义分开,可以创建一个新的.hal
文件来存放类型定义,并在原来的.hal
文件中导入它。可以创建一个名为CanTypes.hal
的文件来存放类型定义:
package android.hardware.can_bus@1.0;
struct CanFrame {
// fields for the struct
}
然后在原来的.hal
文件中导入它:
package android.hardware.can_bus@1.0;
import android.hardware.can_bus@1.0.CanTypes;
interface ICanBus {
// methods and types for the interface
}
问题2:Expecting only package name and version
尝试使用hidl-gen
工具来生成HIDL接口的实现代码时,可能会遇到以下错误:
ERROR: Expecting only package name and version.
ERROR: output handler failed.
这个错误意味着我们的命令行参数不符合hidl-gen
的要求,因为我们提供了多余的或错误的参数。
原因:命令行参数格式错误
hidl-gen
是一个用于生成HIDL接口的实现代码的工具,它有一些特定的命令行参数格式和选项。其中一个必需的参数是HIDL接口的包名和版本号,它应该是这样的:
package@version
比如 如果我们想要生成android.hardware.can_bus@1.0::ICanBus
接口的实现代码,应该提供以下参数:
android.hardware.can_bus@1.0
在这个参数后面添加了其他的内容,例如接口名或文件名,那么hidl-gen
就会报错,因为它只期望一个包名和版本号。
解决方案:修正命令行参数
为了解决这个错误,需要修正我们的命令行参数,只提供包名和版本号。比如 如果我们之前使用了这样的命令:
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0::ICanBus
应该修改为:
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Lc++-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0::ICanBus
这个命令会在输出目default录中生成C++或Android BP的接口代码
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0
这个命令会在输出default目录中生成一个名为Android.bp的文件,包含了HIDL软件包的编译信息。
hardware/interfaces/can_bus$ tree
.
└── 1.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── CanBus.cpp
│ └── CanBus.h
└── ICanBus.hal
问题3:module “android.hardware.can_bus@1.0-service” variant “android_arm64_armv8-a_cortex-a55”: depends on //system/libhwbinder:libhwbinder which is not visible to this module
当尝试编译一个名为android.hardware.can_bus@1.0-service
的HAL服务时,可能会遇到以下错误:
error: hardware/interfaces/can_bus/1.0/service/Android.bp:1:1: module "android.hardware.can_bus@1.0-service" variant "android_arm64_armv8-a_cortex-a55": depends on //system/libhwbinder:libhwbinder which is not visible to this module
10:08:10 soong bootstrap failed with: exit status 1
这个错误意味着我们的HAL服务模块依赖了一个对它不可见的库,即//system/libhwbinder:libhwbinder
。这违反了Soong构建系统的可见性规则,因为每个模块都必须声明它可以访问的其他模块。
原因:可见性属性缺失或错误
Soong构建系统是Android用于编译源代码的工具,它使用一种名为Blueprint的语言来描述模块和它们之间的关系。Blueprint语言有一些属性和关键字来控制模块的可见性,即哪些模块可以访问哪些模块。
其中一个属性是visibility
,它可以在一个模块的定义中指定哪些其他模块可以依赖它。如果想要让一个名为testhal
的模块只对同一个包中的其他模块可见,可以这样写:
cc_library {
name: "testhal",
visibility: [":__subpackages__"],
}
如果想要让一个名为testhal2
的模块对所有其他模块可见,可以这样写:
cc_library {
name: "testhal2",
visibility: ["//visibility:public"],
}
在上面的例子中,//
表示根目录,:
表示包内分隔符,__subpackages__
表示同一个包中的所有子包。
如果一个模块没有指定visibility
属性,那么它默认只对同一个包中的其他模块可见。如果一个模块指定了错误的或不匹配的visibility
属性,那么它可能会导致编译错误。
在我的情况下,HAL服务模块依赖了一个位于系统分区的库,即//system/libhwbinder:libhwbinder
。但这个库的visibility
属性是这样的:
cc_library {
name: "libhwbinder",
visibility: [":__subpackages__"],
}
这个库只对同一个包中的其他模块可见,即只对位于//hardware/interfaces/can_bus/1.0/...
(好像是吧 我猜不可能表示//system/libhwbinder/...
)下的模块可见。而我的HAL服务模块位于//hardware/interfaces/can_bus/1.0/service/...
下,所以它无法访问这个库。
解决方案:修改或添加可见性属性
为了解决这个错误,我尝试两种方案:
- 修改库的可见性属性:修改系统分区中的库,可以修改它们的可见性属性,使其对需要的模块可见。如果想要让
//hardware/interfaces/can_bus/1.0/service/...
对所有HAL服务模块可见,可以这样修改它:
cc_library {
name: "libhwbinder",
export_include_dirs: ["include"],
visibility: [
":__subpackages__",
"//hardware/interfaces/...:service",
],
}
这样就可以在//hardware/interfaces/can_bus/1.0/...
下的任何包含service
的模块中依赖这个库。
或者
+++ b/system/libhwbinder/Android.bp
@@ -66,7 +66,11 @@ cc_library {
export_include_dirs: ["include"],
- visibility: [":__subpackages__"],
+// visibility: [
+// ":__subpackages__",
+// ],
+visibility: ["//visibility:public"],
+
}
这样就所有模块所有路径都能依赖这个库了。
问题4:VNDK library list has been changed
当我尝试编译一个名为android.hardware.can_bus@1.0.so
的HAL时,遇到以下错误:
[ 10% 571/5241] build out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/check-list-timestamp
FAILED: out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/check-list-timestamp
/bin/bash -c "(( diff --old-line-format=\"Removed %L\" --new-line-format=\"Added %L\" --unchanged-line-format=\"\" build/make/target/product/gsi/30.txt out/soong/vndk/vndk.libraries.txt || ( echo -e \" error: VNDK library list has been changed.\\n\" \" Changing the VNDK library list is not allowed in API locked branches.\"; exit 1 )) ) && (mkdir -p out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/ ) && (touch out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/check-list-timestamp )"
Added VNDK-core: android.hardware.can_bus@1.0.so
error: VNDK library list has been changed.
Changing the VNDK library list is not allowed in API locked branches.
10:21:14 ninja failed with: exit status 1
这个错误表示我的HAL被添加到了VNDK库列表中,但在current.txt
文件中并没有列出,导致了编译错误。current.txt
文件是一个定义了当前Android版本所支持的VNDK库列表的文件,它位于build/make/target/product/vndk/
目录下。30.txt
文件是一个定义了Android 11所支持的VNDK库列表的文件,它位于build/make/target/product/gsi/
目录下。
原因:VNDK库列表不一致或不合法
根据我查阅的资料:
VNDK库列表是一个用于保证供应商和系统之间接口稳定性的机制,它规定了哪些框架共享库可以被供应商模块使用,并且在不同的Android版本之间保持兼容性。VNDK库列表有以下几个特点:
- VNDK库列表是按照字母顺序排列的。
- VNDK库列表只包含符合条件的VNDK库(Eligible-VNDK)和VNDK-core库。
- VNDK库列表不包含LL-NDK库、VNDK-SP库、VNDK-SP-Ext库、VNDK-Ext库、FWK-ONLY库和SP-HAL库。
- VNDK库列表在API锁定分支中不允许更改。
API锁定分支是指已经发布或即将发布的Android版本分支,例如android-11或android-s-beta-2。在这些分支中,VNDK库列表已经被冻结,不能再添加或删除任何库。这是为了保证系统分区和供应商分区之间的兼容性,以及支持框架专用更新(即只更新系统分区而不更新供应商分区)。
如果我们在API锁定分支中尝试修改VNDK库列表,或者添加了不符合VNDK标准的库到VNDK库列表中,那么编译系统会报错,并停止构建。
解决方案:根据HAL的性质和用途决定是否添加到VNDK
为了解决这个错误,需要根据我的HAL的性质和用途来决定是否应该将其添加到VNDK中。如果我的HAL确实需要作为VNDK的一部分,可以按照以下步骤操作:
-
更新
current.txt
:在current.txt
文件中,根据我的HAL的性质,将android.hardware.can_bus@1.0.so
添加到合适的位置。如果它是一个核心VNDK库,可以将它添加到VNDK-core
部分。必须注意按照字母顺序插入,不然会编译报错。 -
更新
30.txt
:30.txt
是Android 11的VNDK库列表。如果修改了current.txt
,应该在30.txt
中进行相同的修改,以确保两者保持一致。必须注意按照字母顺序插入。
但如果我们的HAL不应该是VNDK的一部分,那么应该从构建配置中移除任何将其标记为VNDK的部分,并确保它不会被添加到VNDK库列表中。可以在HAL模块的Android.bp文件中添加一个属性(目前还没搞懂具体区别到底是啥,反正看网上这么说):
vndk: {
enabled: false,
},
这样系统就不会将该模块视为VNDK库,而是一个普通的HAL模块。该模块就不会被系统分区和供应商分区共享,而是只能被供应商分区使用。
这个问题之前第一次搞HIDL的时候 搞了我好久,还好之前添加过 根据我查阅的笔记。。。
简而言之我告诉大家一个非常简单的办法out\soong\vndk\vndk.libraries.txt
和build\target\product\gsi\30.txt
这两个文件用对比工具比完直接用out目录下的比到build目录下直接ok。
更多VNDK可以参考以下链接:
- 供应商原生开发套件 (VNDK):介绍了VNDK的概念、资源、分类和版本控制。
- Android : 供应商原生开发套件 (VNDK):介绍了VNDK的概述、框架和供应商之间库的区分、安全策略等。
- 什么是VNDk?:回答了关于VNDK的基本问题。
- 如何使用 VNDk 扩展导出的符号?:介绍了如何使用VNDK扩展来扩展AOSP库而不破坏兼容性。
问题5:hwservicemanager找不到HAL接口的错误
09-09 15:24:22.448 8915 8915 I android.hardware.can_bus@1.0-service: CanBusService created
09-09 15:24:22.449 141 141 I hwservicemanager: getTransport: Cannot find entry android.hardware.can_bus@1.0::ICanBus/default in either framework or device manifest.
09-09 15:24:22.450 8915 8915 E HidlServiceManagement: Service android.hardware.can_bus@1.0::ICanBus/default must be in VINTF manifest in order to register/get.
这个错误表示我的HAL服务尝试注册到hwservicemanager
,但是hwservicemanager
在VINTF(Vendor Interface)清单中找不到相应的条目。VINTF清单是Android 8.0及更高版本中引入的,用于描述HAL和框架之间的接口。
为了解决这个错误,需要确保我们的HAL接口已经被添加到VINTF清单中。以下是如何做到这一点的步骤:
步骤1:创建或修改VINTF清单
在源代码目录中,通常在system
目录下,找到一个名为manifest.xml
的文件。这个文件用于描述我们的设备提供的HAL接口和版本,以及其他设备相关的信息,如SELinux政策版本等。
步骤2:添加HAL接口到清单
在manifest.xml
中,添加我们的HAL接口。需要指定接口的名称、传输方式、版本和实例。例如,如果我们想要添加一个名为android.hardware.can_bus@1.0::ICanBus
的接口,并且它使用hwbinder作为传输方式,并且有一个名为default的实例,可以这样写:
<manifest version="1.0" type="device">
。。。
<hal format="hidl">
<name>android.hardware.can_bus</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>ICanBus</name>
<instance>default</instance>
</interface>
</hal>
<!-- 其他HAL接口 -->
。。。
</manifest>
可以在一个<hal>
标签中添加多个版本和实例,也可以添加其他格式的HAL接口,如AIDL或native。
更多关于hwservicemanager和VINTF清单的信息,你可以参考以下链接:
- HIDL:介绍了HIDL语言和架构,以及如何使用hwservicemanager来管理HIDL服务。
- 供应商接口对象:介绍了VINTF对象的设计和作用,以及如何使用清单和矩阵来描述和匹配HAL接口。
问题6:调试和解决extends属性引用非VNDK库的错误
error: hardware/interfaces/can_bus/1.0/service/Android.bp:2:1: module "android.hardware.can_bus@1.0-service" variant "android_vendor.30_arm64_armv8-a_cortex-a55": `extends` refers a non-vndk module "libhidltransport"
14:34:14 soong bootstrap failed with: exit status 1
这个错误提示我在system?分区中引用了一个非VNDK的库,即libhidltransport
。在Android 8.0及更高版本中,为了确保设备向后兼容性,Google引入了VNDK概念。VNDK库是那些可以在vendor分区中安全使用的库。
为了解决这个问题,以下是我的尝试:
方法1:移除extends属性
如果不需要继承libhidltransport
的属性,可以简单地从vndk
块中移除extends
属性。比如 HAL模块的Android.bp文件中,可以这样写:
cc_binary {
name: "android.hardware.can_bus@1.0-service",
vendor: true,
vndk: {
enabled: true,
support_system_process: false,
},
srcs: ["CanBus.cpp"],
shared_libs: [
"android.hardware.can_bus@1.0",
"libhidltransport",
"libhidlbase",
"libutils",
"libcutils",
"liblog",
],
}
这样 就不会引用非VNDK库的属性,而是使用默认的属性。
方法2:使用VNDK版本的库
如果libhidltransport
有一个VNDK版本,例如libhidltransport_vndk
,我们应该在shared_libs
中使用它,并在extends
中指定它。在我们的HAL模块的Android.bp文件中,可以这样写:
cc_binary {
name: "android.hardware.can_bus@1.0-service",
vendor: true,
vndk: {
enabled: true,
support_system_process: false,
extends: "libhidltransport_vndk",
},
srcs: ["CanBus.cpp"],
shared_libs: [
"android.hardware.can_bus@1.0",
"libhidltransport_vndk",
"libhidlbase",
"libutils",
"libcutils",
"liblog",
],
}
就可以继承VNDK库的属性,并且不会引用非VNDK库。
还有一种办法,和问题3类似,就是其实libhidltransport也是有个可见的属性,需要在源码中搜下,反正在Android.bp中 搞了老半天 头有点晕,我直接把这个libhidltransport依赖库给干掉了,也没啥影响 也没搞懂原因。这个就当作坑吧 后面再填上。
问题7:如何调试和解决init进程无法启动服务的错误
09-09 15:50:30.479 0 0 E init : Control message: Could not ctl.start for 'vendor.hw_canbus' from pid: 2563 (start vendor.hw_canbus): File /system/bin/hw/android.hardware.can_bus@1.0-service(labeled "u:object_r:system_file:s0") has incorrect label or no domain transition from u:r:init:s0 to another SELinux domain defined. Have you configured your service correctly? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials
09-09 15:50:30.357 2563 2563 W libc : Unable to set property "ctl.start" to "vendor.hw_canbus": error code: 0x20
这个错误表示HAL服务无法通过init
进程启动,因为它没有正确的SELinux上下文或域转换。init
进程是Android系统中负责启动和管理服务的核心进程,它有自己的SELinux上下文(通常是u:r:init:s0
),并且需要遵循SELinux策略来执行服务的启动和停止。
为了解决这个错误,需要确保以下几点:
步骤1:确认文件上下文
文件上下文是SELinux用来标记文件的安全属性的一种机制,它包括用户、角色、类型和可选的等级。文件上下文可以通过ls -Z
命令查看,例如:
$ ls -Z /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x root root u:object_r:system_file:s0 /system/bin/hw/android.hardware.can_bus@1.0-service
这里可以看到文件的类型是system_file
,这是一个通用的类型,不适合用于我们的HAL服务。我们需要为HAL服务定义一个专门的类型,比如can_bus_exec
,并且在编译时将文件上下文设置为该类型。
步骤2:服务定义
服务定义是在.rc
文件中指定HAL服务的启动和停止方式、依赖关系、优先级、资源限制等信息的一种机制。.rc
文件通常位于我们的设备特定的源代码目录中,例如system/etc/init/android.hardware.can_bus@1.0-service.rc
。在.rc
文件中,需要为我们的HAL服务添加一个类似于以下的标签:
service vendor.hw_canbus /system/bin/hw/android.hardware.can_bus@1.0-service
class hal
user system
group system
seclabel u:object_r:hal_canbus_default_exec:s0
也可以在file_contexts文件中添加以下行:
/(vendor|system)/bin/hw/android\.hardware\.canbus@1\.0-service u:object_r:hal_canbus_default_exec:s0
这个段落表示,定义了一个名为vendor.hw_canbus
的服务,它执行了一个名为/system/bin/hw/android.hardware.can_bus@1.0-service
的程序。它属于main
类别,以系统用户和系统组运行,并且有一个名为 seclabel u:object_r:hal_canbus_default_exec:s0
的SELinux上下文。它是一个一次性服务,即只运行一次而不会重启。
步骤3:重新编译并确认
完成更改后,在设备上运行以下命令来检查我们的HAL服务是否已经被正确启动
如果一切正常,可以看到类似以下的输出:
09-11 09:07:46.421 9125 9125 I android.hardware.can_bus@1.0-service: CanBusService created
09-11 09:07:46.424 9125 9125 I HidlServiceManagement: Registered android.hardware.can_bus@1.0::ICanBus/default
09-11 09:07:46.424 9125 9125 I HidlServiceManagement: Removing namespace from process name android.hardware.can_bus@1.0-service to can_bus@1.0-service.
09-11 09:07:46.424 9125 9125 I android.hardware.can_bus@1.0-service: CanBusService is ready.
rk
#输出结果显示了一个名为android.hardware.can_bus@1.0-service的进程,其进程ID为3435,它是由root用户启动的,并且当前处于睡眠状态(S)
3568_r:/ # ps -A | grep can
root 3435 567 10773968 2788 binder_thread_read 0 S android.hardware.can_bus@1.0-service
#输出结果显示了一个名为android.hardware.can_bus@1.0::ICanBus/default的HAL服务。这表示系统上有一个实现了android.hardware.can_bus@1.0接口的HAL服务,并且它的实例名为default。
rk3568_r:/ # lshal | grep can
FM N android.hardware.can_bus@1.0::ICanBus/default 0/1 3435 148
标签调试过程
rk3568_r:/system # find -name "*can*.rc"
./etc/init/android.hardware.can_bus@1.0-service.rc
rk3568_r:/system # cat ./etc/init/android.hardware.can_bus@1.0-service.rc
on boot
start vendor.hw_canbus
service vendor.hw_canbus /system/bin/hw/android.hardware.can_bus@1.0-service
class hal
user system
group system
seclabel u:object_r:hal_canbus_default_exec:s0
rk3568_r:/system # start vendor.hw_canbus
Unable to start service 'vendor.hw_canbus'
See dmesg for error reason.
rk3568_r:/ # ls -llZ /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x 1 root shell u:object_r:system_file:s0 16616 2023-09-09 15:06:27.000000000 +0800 /system/bin/hw/android.hardware.can_bus@1.0-service
rk3568_r:/ # restorecon /system/bin/hw/android.hardware.can_bus@1.0-service
SELinux: Loaded file_contexts
rk3568_r:/ # ls -llZ /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x 1 root shell u:object_r:system_file:s0 16616 2023-09-09 15:06:27.000000000 +0800 /system/bin/hw/android.hardware.can_bus@1.0-service
rk3568_r:/ # chcon u:object_r:hal_canbus_default_exec:s0 /system/bin/hw/android.hardware.can_bus@1.0-service
r:hal_canbus_default_exec:s0 /system/bin/hw/android.hardware.can_bus@1.0-servic^C <
130|rk3568_r:/ # ls -llZ /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x 1 root shell u:object_r:hal_canbus_default_exec:s0 16616 2023-09-09 15:06:27.000000000 +0800 /system/bin/hw/android.hardware.can_bus@1.0-service
这表示我们的HAL服务已经成功启动,并且有正确的SELinux上下文。
问题8:提示android/hardware/can_bus/1.0/ICanBus.h文件找不到
我在增加native的时候 编译frameworks/base/services/core/jni/com_android_server_SystemCanBusService.cpp
时,遇到了一个错误,提示android/hardware/can_bus/1.0/ICanBus.h
文件找不到。
frameworks/base/services/core/jni/com_android_server_SystemCanBusService.cpp:6:10: fatal error: 'android/hardware/can_bus/1.0/ICanBus.h' file not found
#include <android/hardware/can_bus/1.0/ICanBus.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
原因:没有被正确生成
android/hardware/can_bus/1.0/ICanBus.h
头文件没有被正确生成或者其路径没有被正确包含在编译时的头文件搜索路径中。
解决方案:修改jni Android.bp 让库被正确地包含在编译依赖中
- 使用
hidl-gen
命令手动生成所需的头文件。这个命令会在hardware/interfaces/can_bus/1.0/default
目录下生成一个gen
子目录,其中包含android/hardware/can_bus/1.0/ICanBus.h
文件。
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Lc++-headers \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0
hardware$ find -name "ICanBus.h"
./interfaces/can_bus/1.0/default/android/hardware/can_bus/1.0/ICanBus.h
-
修改
frameworks/base/services/core/jni/Android.bp
文件,确保android.hardware.can_bus@1.0
库被正确地包含在编译依赖中。文章来源:https://www.toymoban.com/news/detail-821392.html@@ -155,6 +156,7 @@ cc_defaults { "android.hardware.gnss.visibility_control@1.0", "android.hardware.input.classifier@1.0", "android.hardware.ir@1.0", + "android.hardware.can_bus@1.0", "android.hardware.light@2.0", "android.hardware.power@1.0", "android.hardware.power@1.1",
通过上述步骤 可以解决编译时找不到ICanBus.h
文件的问题。文章来源地址https://www.toymoban.com/news/detail-821392.html
到了这里,关于Android HAL深入探索(5): 调试HAL报错与解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!