1. 初始化相机HAL模块失败
任务说明
本案例目标:排查并解决相机HAL模块加载失败的问题,确保hal_module_info正确注册。你将通过一个最小可复现的HAL模块实现,模拟加载失败场景,定位根因并修复。
问题现象
在Android系统启动或相机服务调用hw_get_module(CAMERA_HARDWARE_MODULE_ID, &module)时,返回-ENOENT或module->hal_api_version不匹配,导致相机服务无法正常启动。
根因分析
HAL模块加载失败通常由以下原因之一引起:
hal_module_info结构体未正确导出(符号缺失或名称错误);- 模块ID与
hw_get_module请求的ID不一致; - 模块的
hal_api_version或module_api_version版本不兼容; - Android.bp/Android.mk中未正确链接或未将模块打包到
/vendor/lib/hw/或/system/lib/hw/。
最小复现实现
以下代码展示一个标准的相机HAL模块实现,其中HAL_MODULE_INFO_SYM是必须导出的符号:
// camera_hal.cpp
#include <hardware/hardware.h>
#include <hardware/camera.h>
#include <cutils/log.h>
// 相机设备打开函数(简化)
static int camera_device_open(const struct hw_module_t* module,
const char* name,
struct hw_device_t** device) {
// 实际实现中在此创建设备对象
return 0;
}
// 模块方法表
static struct hw_module_methods_t camera_module_methods = {
.open = camera_device_open,
};
// 相机HAL模块结构体
struct camera_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_2_4,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "Camera HAL Module",
.author = "Your Company",
.methods = &camera_module_methods,
.dso = nullptr,
.reserved = {0},
},
// 以下为camera_module_t扩展字段,按需初始化
};
编译配置(Android.bp)
cc_library_shared {
name: "camera.primary",
vendor: true,
relative_install_path: "hw",
srcs: ["camera_hal.cpp"],
shared_libs: [
"libhardware",
"libcutils",
"liblog",
],
}
验证方法
将编译产物camera.primary.so推送到设备/vendor/lib/hw/目录后,执行以下命令验证模块是否正确注册:
adb shell "ls -l /vendor/lib/hw/camera.primary.so"
adb shell "cat /proc/kallsyms | grep HAL_MODULE_INFO_SYM" # 确认符号已导出
在应用层执行测试程序调用hw_get_module:
#include <hardware/hardware.h>
#include <hardware/camera.h>
int main() {
const hw_module_t* module = nullptr;
int ret = hw_get_module(CAMERA_HARDWARE_MODULE_ID, &module);
if (ret != 0) {
ALOGE("hw_get_module failed: %d", ret);
return -1;
}
ALOGI("Module loaded: %s, api_version: %d.%d",
module->name,
(module->hal_api_version >> 8) & 0xFF,
module->hal_api_version & 0xFF);
return 0;
}
判定标准
- 若
hw_get_module返回0且日志打印模块名称与版本号,说明hal_module_info注册成功,问题解决; - 若返回
-ENOENT,检查camera.primary.so是否存在于正确路径,且id字段是否为CAMERA_HARDWARE_MODULE_ID; - 若返回
-EINVAL,检查tag是否为HARDWARE_MODULE_TAG,以及版本号是否在系统支持范围内。
常见修复项
- 确认
HAL_MODULE_INFO_SYM拼写正确(注意是SYM不是SIM); - 确认
id字段与请求ID一致,相机模块必须使用CAMERA_HARDWARE_MODULE_ID(即"camera"); - 确认Android.bp中
relative_install_path: "hw",确保so文件安装到/vendor/lib/hw/; - 若使用Treble架构,确认
vendor: true且模块位于vendor分区。
完成上述修复后重新编译并验证,即可解决相机HAL模块加载失败问题。