1. 初始化相机HAL模块失败

任务说明

本案例目标:排查并解决相机HAL模块加载失败的问题,确保hal_module_info正确注册。你将通过一个最小可复现的HAL模块实现,模拟加载失败场景,定位根因并修复。

问题现象

在Android系统启动或相机服务调用hw_get_module(CAMERA_HARDWARE_MODULE_ID, &module)时,返回-ENOENT或module->hal_api_version不匹配,导致相机服务无法正常启动。

根因分析

HAL模块加载失败通常由以下原因之一引起:

  1. hal_module_info结构体未正确导出(符号缺失或名称错误);
  2. 模块ID与hw_get_module请求的ID不一致;
  3. 模块的hal_api_version或module_api_version版本不兼容;
  4. 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,以及版本号是否在系统支持范围内。

常见修复项

  1. 确认HAL_MODULE_INFO_SYM拼写正确(注意是SYM不是SIM);
  2. 确认id字段与请求ID一致,相机模块必须使用CAMERA_HARDWARE_MODULE_ID(即"camera");
  3. 确认Android.bp中relative_install_path: "hw",确保so文件安装到/vendor/lib/hw/;
  4. 若使用Treble架构,确认vendor: true且模块位于vendor分区。

完成上述修复后重新编译并验证,即可解决相机HAL模块加载失败问题。