1. 初始化Camera HAL模块
任务说明
本案例实现Android Camera HAL模块的加载与初始化,核心目标是:定义符合硬件抽象层规范的hw_module_t结构体,填充模块基本信息,并完成open函数指针的赋值,使上层Camera Service能够通过标准HAL接口成功加载并打开Camera设备。
模块头文件定义
// camera_hal.h
#ifndef ANDROID_CAMERA_HAL_H
#define ANDROID_CAMERA_HAL_H
#include <hardware/hardware.h>
#include <hardware/camera_common.h>
#include <cutils/log.h>
// 自定义Camera HAL模块结构体,扩展自hw_module_t
typedef struct camera_hw_module {
hw_module_t common;
// 可在此处添加厂商自定义字段
int vendor_specific_value;
} camera_hw_module_t;
// HAL模块打开的设备句柄结构体
typedef struct camera_hw_device {
hw_device_t common;
// 设备相关操作函数指针将在后续案例中填充
int (*device_specific_op)(struct camera_hw_device* dev);
} camera_hw_device_t;
// HAL模块入口点,由hw_get_module()调用
int camera_hal_open(const hw_module_t* module, const char* name, hw_device_t** device);
#endif // ANDROID_CAMERA_HAL_H
模块实现代码
// camera_hal.cpp
#define LOG_TAG "camera_hal"
#include "camera_hal.h"
#include <cutils/log.h>
// 前置声明:设备打开函数
static int camera_device_open(const hw_module_t* module, const char* name,
hw_device_t** device);
// 模块open函数指针赋值目标
static int camera_module_open(const hw_module_t* module, const char* name,
hw_device_t** device) {
ALOGI("camera_module_open: name = %s", name);
return camera_device_open(module, name, device);
}
// 静态模块实例,hw_module_t结构体填充
static struct hw_module_methods_t camera_module_methods = {
.open = camera_module_open
};
// HAL_MODULE_INFO_SYM是hw_get_module()查找的符号
struct camera_hw_module 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 = "Android Camera HAL Course",
.methods = &camera_module_methods,
.dso = nullptr,
.reserved = {0}
},
.vendor_specific_value = 0x2019
};
// 设备打开实现:当前仅完成设备结构体分配与基础初始化
static int camera_device_open(const hw_module_t* module, const char* name,
hw_device_t** device) {
if (module == nullptr || device == nullptr) {
ALOGE("camera_device_open: invalid argument");
return -EINVAL;
}
// 分配设备结构体内存
camera_hw_device_t* dev = (camera_hw_device_t*)calloc(1, sizeof(camera_hw_device_t));
if (dev == nullptr) {
ALOGE("camera_device_open: failed to allocate memory");
return -ENOMEM;
}
// 填充hw_device_t公共字段
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = CAMERA_DEVICE_API_VERSION_2_4;
dev->common.module = (hw_module_t*)module;
dev->common.close = nullptr; // close函数将在设备操作实现案例中赋值
// 初始化厂商自定义字段
dev->device_specific_op = nullptr;
// 将设备指针返回给调用者
*device = &dev->common;
ALOGI("camera_device_open: device opened successfully");
return 0;
}
Android.bp构建配置
// Android.bp
cc_library_shared {
name: "camera.hello_hal",
vendor: true,
relative_install_path: "hw",
srcs: ["camera_hal.cpp"],
shared_libs: [
"liblog",
"libcutils",
"libhardware",
],
header_libs: ["libhardware_headers"],
}
编译与部署
# 在Android源码根目录执行
source build/envsetup.sh
lunch <your_target>
mmm hardware/camera_hal_course/
# 编译产物路径
# out/target/product/<device>/vendor/lib64/hw/camera.hello_hal.so
验证方法
编写以下测试程序验证模块加载与初始化是否成功:
// hal_test.cpp
#include <hardware/hardware.h>
#include <hardware/camera_common.h>
#include <cstdio>
int main() {
const hw_module_t* module = nullptr;
int ret = hw_get_module(CAMERA_HARDWARE_MODULE_ID, &module);
if (ret != 0) {
printf("FAIL: hw_get_module returned %d\n", ret);
return -1;
}
// 验证模块结构体字段
printf("Module id: %s\n", module->id);
printf("Module name: %s\n", module->name);
printf("Module api version: %d\n", module->module_api_version);
printf("Module methods open: %p\n", module->methods->open);
// 验证open函数指针已赋值
if (module->methods->open == nullptr) {
printf("FAIL: open function pointer is null\n");
return -1;
}
// 尝试打开设备
hw_device_t* device = nullptr;
ret = module->methods->open(module, "0", &device);
if (ret != 0 || device == nullptr) {
printf("FAIL: device open returned %d\n", ret);
return -1;
}
printf("PASS: HAL module loaded and device opened successfully\n");
printf("Device tag: %d\n", device->tag);
printf("Device module pointer: %p\n", device->module);
return 0;
}
判定标准:
- 编译无错误,生成
camera.hello_hal.so动态库; - 测试程序执行后输出
PASS: HAL module loaded and device opened successfully; - 模块的
id字段为"camera",methods->open非空; - 设备打开后返回的
hw_device_t结构体tag正确且module指针指向加载的模块实例。
预期输出(由代码逻辑直接推出):
Module id: camera
Module name: Camera HAL Module
Module api version: 512
Module methods open: 0x...
PASS: HAL module loaded and device opened successfully
Device tag: 1
Device module pointer: 0x...
本案例完成了HAL模块的静态定义、hw_module_t结构体填充、open函数指针赋值以及设备打开的基础实现。上层通过hw_get_module()即可加载该模块,并通过methods->open完成设备句柄的创建,为后续Camera设备操作函数的实现奠定基础。