海思平台 Camera HAL 模块编译配置与参数传递路径实战解析


关键词
HiSilicon、Camera HAL、HAL 模块编译、参数传递、HISP、媒体驱动、帧控制、ISP pipeline、sensor 适配


摘要
在海思(HiSilicon)平台上进行 Camera HAL 模块开发与调试,必须深入理解其底层编译体系、模块依赖配置以及 HAL 与 HISP(HiSilicon ISP)之间的参数交互路径。本文结合主流智能终端 SoC(如 Hi3559AV100、Hi3516CV500)平台实战,系统梳理 Camera HAL 模块的编译组织逻辑、参数下发机制、流控路径与常见问题处理方法,并对 HAL 与驱动之间的交互协议、接口封装及调试策略展开深入探讨,帮助开发者在复杂的多 Sensor 系统中高效构建稳定的 Camera 体系。


目录

  1. 海思平台 Camera HAL 框架结构总览
  2. HAL 模块编译配置体系:makefile、模块依赖与 BoardConfig.mk
  3. Sensor 参数配置方式:hisp_cfg.xml 与 ae_cfg.xml 路径解析
  4. HAL 层参数下发机制:pipeline control → ISP → sensor interface
  5. 图像流绑定逻辑:VideoNode 与 MediaDevice 节点的 HAL 映射
  6. HAL 与驱动交互路径:ioctl、media entity 链接与 buffer 调度
  7. 多模组系统适配策略:Sensor 多路加载、动态配置与流切换
  8. 工程实战调试建议:日志抓取、参数追踪与平台兼容性分析

1. 海思平台 Camera HAL 框架结构总览

在海思平台上,Camera HAL 模块的整体框架融合了其定制化的 ISP 管理层(HISP)与标准化的 Android HAL 接口。相较于 QCOM 和 MTK 平台,海思的 HAL 实现更强调模块解耦和 XML 配置驱动,构建路径覆盖从应用层 API 到驱动底层的完整图像采集与处理链路。

主要结构包括

  • libcamera_hal.so:核心 HAL 实现,负责请求接收、参数处理、请求下发。
  • libisp_api.so / libhisp.so:海思自研 ISP 接口库,封装底层 ISP、AE/AWB/AF 控制与硬件配置调用。
  • hisp_cfg.xml:系统主配置入口,定义每颗 sensor 的初始化参数、图像分辨率、ISP pipe 绑定信息等。
  • /dev/mediaX/dev/videoX/dev/v4l-subdevX:标准 V4L2 媒体节点,供 HAL 模块通过 IOCTL 调用通信。

流控链路

应用层 (Camera APP)
    ↓
frameworks/av/camera
    ↓
CameraProvider (HIDL)
    ↓
libcamera_hal.so (HAL3)
    ↓
libhisp.so + hisp_cfg.xml
    ↓
Sensor driver + ISP driver
    ↓
V4L2 media pipeline → ISP → DMA

HAL 层扮演连接应用与驱动的重要中介角色,主要负责:初始化设备、加载配置文件、构建 Stream、封装 Metadata、完成图像流 Buffer 交互。


2. HAL 模块编译配置体系:makefile、模块依赖与 BoardConfig.mk

海思平台的 HAL 模块编译体系构建在 Android SoC BSP 的基础之上,依赖典型的 Android build system。不同于标准的 Google HAL 接口调用逻辑,HiSilicon 提供了多个补丁与私有库文件,用于连接 HISP 框架与 ISP/AE/AWB 组件。

2.1 编译入口结构

device/hisilicon/<soc_name>/ 目录下,Camera HAL 相关的模块编译路径通常包含:

  • hardware/hisilicon/camera/hal/:HAL 主目录,包含 CameraHAL.cppHAL3Session.cpp 等核心实现。
  • device.mk / BoardConfig.mk:指定 HAL 模块的编译开关、库依赖、系统权限。
  • Android.mkAndroid.bp:配置 HAL 模块编译依赖,如下所示:
include $(CLEAR_VARS)
LOCAL_MODULE := camera.hisilicon
LOCAL_SRC_FILES := CameraHAL.cpp HAL3Session.cpp ...
LOCAL_SHARED_LIBRARIES := libhisp liblog libcutils libutils
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

2.2 HISP SDK 依赖库引入

海思提供的闭源 libhisp.solibisp_api.so 通常位于:

vendor/hisilicon/proprietary/lib/hisp/

这些库在编译时必须在 LOCAL_PREBUILT_LIBS 中显式声明:

LOCAL_PREBUILT_LIBS := libhisp.so libisp_api.so

此外,还需将其加入 PRODUCT_PACKAGES 以便系统镜像加载。

2.3 配置 XML 的编译规则

Sensor 参数配置通过 hisp_cfg.xmlae_cfg.xml 形式提供,需在 Makefile 中定义复制路径,例如:

PRODUCT_COPY_FILES += \
    $(LOCAL_PATH)/configs/hisp_cfg.xml:system/etc/camera/hisp_cfg.xml \
    $(LOCAL_PATH)/configs/ae_cfg.xml:system/etc/camera/ae_cfg.xml

这些 XML 文件在 HAL 初始化时被读取,驱动实际生效参数依赖于这些静态配置。


3. Sensor 参数配置方式:hisp_cfg.xmlae_cfg.xml 路径解析

在海思平台中,Sensor 与 ISP 的初始化参数主要通过 XML 配置文件驱动,不依赖固定代码编写。这种方式提供了极高的灵活性,适用于多 Sensor 快速适配场景。

3.1 hisp_cfg.xml 结构说明

文件路径一般为:

/system/etc/camera/hisp_cfg.xml

该文件为 HAL 初始化阶段的主要配置源,其核心字段包括:

  • SensorList: 定义支持的 sensor 模组及其 pipeline 配置。
  • Pipe: 每路 sensor 所使用的 ISP pipe、输出格式(YUV/RGB)、分辨率等。
  • Format: 支持的 stream type,如 preview、video、capture。
  • SensorInterface: 定义 CSI 通道数、MCLK 配置、数据位宽、pixel clock 等。
  • Tuning: 包含默认的 AE、AWB、NR、Gamma 参数组索引。
<SensorList>
  <Sensor name="imx586" id="0x01" interface="mipi" pipe="Pipe0">
    <Format type="preview" width="1920" height="1080" fps="30" />
    <SensorInterface lanes="4" mclk="24000000" dataformat="RAW10"/>
    <Tuning ae="0" awb="0" nr="1" gamma="2"/>
  </Sensor>
</SensorList>

通过该 XML,HAL 可动态配置每颗 Sensor 的拓扑绑定与输出模式。

3.2 ae_cfg.xml / awb_cfg.xml 说明

路径通常如下:

/system/etc/camera/ae_cfg.xml
/system/etc/camera/awb_cfg.xml

这些配置文件负责提供 ISP 各模块的算法调参内容,包括曝光增益表、黑电平偏移、目标亮度等。例如 ae_cfg 中:

<AEConfig>
  <TargetBrightness value="120"/>
  <GainTable>
    <Gain index="0" value="1.0"/>
    <Gain index="1" value="2.0"/>
  </GainTable>
</AEConfig>

这些表项由 HAL 在运行时加载,通过内存接口下发至 HISP/ISP 驱动,驱动将参数同步至 Sensor 控制器或 AE 模块。


4. HAL 层参数下发机制:pipeline control → ISP → sensor interface

Sensor 的所有参数并非由 HAL 直接操作硬件,而是通过封装结构体进行间接下发,配合内部 pipeline 管理机制完成。

4.1 HAL Pipeline 控制结构

每一个 CaptureRequest 或 streamConfiguration 请求到达 HAL 后,会被转换为内部的 PipelineConfig 实例,其中包括:

  • Sensor ID 与 Pipe 映射关系
  • AE/AWB/AF 状态管理句柄
  • 请求帧率 / 曝光 / 增益等参数

HAL 将这些请求推入控制线程,调用如下封装接口:

HispInterface::configurePipe(PipelineConfig config);

4.2 ISP 接口调用流程

HAL 实现中通常会调用 libhisp.so 中的接口,例如:

HISP_SetSensorMode(sensor_id, resolution, format);
HISP_SetAeParam(sensor_id, gain, exposure);

这些 API 会通过 /dev/hisp_ctrl 文件节点以 IOCTL 或 mmap 内存交互方式传递控制命令。

4.3 Sensor interface 配置动作

最终生效的参数下发步骤为:

  1. HAL 中解析请求并封装 pipeline 配置
  2. 通过 HISP 接口下发曝光 / 增益 / 帧率配置
  3. HISP 与 sensor driver 协议通信(如 I2C 写寄存器)
  4. Sensor 接收命令并执行,比如设置 VTS/HTS、gain 表项

此过程一般由 HISP_Manager 协议层统一调度,不同 sensor 可配置为单独 channel 执行,也可在 group 模式下并行同步。


5. 图像流绑定逻辑:VideoNode 与 MediaDevice 节点的 HAL 映射

在海思平台的 Camera HAL 实现中,图像流的绑定依赖于 VideoNode 与 MediaDevice 的拓扑映射关系。HAL 层需准确识别系统中注册的 Video 设备节点,并通过 media controller 提供的实体信息完成逻辑 pipeline 的构建。

5.1 VideoNode 与 MediaDevice 的拓扑关系

一个典型的媒体拓扑如下:

[Sensor Subdev] -> [MIPI RX] -> [ISP Subdev] -> [Video Output Node]

其中:

  • Sensor/ISP 为 subdev 类型节点
  • Video Output(如 /dev/video0)为 VideoDevice
  • MediaDevice(如 /dev/media0)提供整个 pipeline 的 graph 查询能力

HAL 初始化时通常通过如下步骤完成绑定:

// 1. Open media device
int media_fd = open("/dev/media0", O_RDWR);

// 2. Query topology
MEDIA_IOC_ENUM_ENTITIES -> MEDIA_IOC_ENUM_LINKS

// 3. 解析出与 ISP 输出节点连接的 videoX
std::string videonode = find_linked_video_node("isp_subdev0");

这样,HAL 便能准确地将请求发送到对应的 VideoNode。

5.2 逻辑流绑定关键点
  • 多 ISP 平台会注册多个 VideoNode,需与 Sensor ID 一一映射
  • 绑定时应校验 MediaEntity 是否为 MEDIA_ENT_F_PROC_VIDEO_SCALER 类型,保证输出节点具备缩放能力
  • HAL 应动态配置 route-table 来支撑 dual cam 等多路独立路径同步

6. HAL 与驱动交互路径:ioctl、media entity 链接与 buffer 调度

HAL 与驱动之间的交互主要分为两大类:

  • 控制类指令(如 VIDIOC_S_FMT, VIDIOC_REQBUFS 等)通过 ioctl 下发
  • 图像数据类交互通过 buffer queue 实现,包括 enqueue/dequeue 操作
6.1 IOCTL 调用栈路径

HAL 通常通过标准 V4L2 ioctl 接口进行设备初始化与参数设置:

int fd = open("/dev/video0", O_RDWR);
v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt.fmt.pix.width = 1920;
fmt.fmt.pix.height = 1080;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;

ioctl(fd, VIDIOC_S_FMT, &fmt);

同时还包括:

  • VIDIOC_REQBUFS: 申请 buffer
  • VIDIOC_QBUF / DQBUF: 入队与出队
  • VIDIOC_STREAMON / STREAMOFF: 开始与停止流
6.2 MediaEntity 链接激活

在采用 Media Controller 架构的系统中,流通路径必须手动或脚本化配置:

# 通过 media-ctl 工具手动配置 pipeline
media-ctl -d /dev/media0 \
  --set-v4l2 '"sensor":0[fmt:SRGGB10/1920x1080@1/30]' \
  --set-v4l2 '"isp_subdev":0[fmt:SRGGB10/1920x1080@1/30]' \
  --link '"sensor":0 -> "isp_subdev":0[1]'

在 HAL 层,这一过程通常封装为调用 media_configure_links() 函数,支持自动识别并激活:

bool MediaManager::configure_links(sensor_id) {
  // 调用 MEDIA_IOC_SETUP_LINK 使能 pipeline
}

6.3 Buffer 调度机制

HAL 通过以下机制完成帧数据调度:

  1. 请求 buffer(VIDIOC_REQBUFS
  2. 循环入队空 buffer(VIDIOC_QBUF
  3. 启动流(VIDIOC_STREAMON
  4. 接收帧完成通知(VIDIOC_DQBUF
  5. 回收 buffer 或重新入队(VIDIOC_QBUF

这套机制在 QCamera3 或 MTK HAL 中都做了深度封装,用于隐藏底层细节并实现流复用、流抢占、流暂停等高级行为。


7. 多模组系统适配策略:Sensor 多路加载、动态配置与流切换

在海思平台实际部署中,Camera 多模组系统(如主摄 + 广角、ToF、深景、前置)广泛应用于中高端终端产品。为满足多模组快速加载、资源复用与高效调度,HAL 层需支持:

7.1 多 Sensor 节点的动态加载机制

平台常将多个 sensor 节点写入统一设备树,并通过节点 ID 或 alias 区分:

&i2c1 {
    ov5640@3c {
        compatible = "hisilicon,ov5640";
        reg = <0x3c>;
        status = "okay";
    };

    gc5035@37 {
        compatible = "hisilicon,gc5035";
        reg = <0x37>;
        status = "okay";
    };
};

HAL 需实现 sensor_list 管理机制,支持 runtime 注册多个 sensor,并根据调用请求动态切换。

7.2 流切换控制策略

在多摄使用场景(如 Zoom、Portrait)下,sensor 的工作状态需要根据场景切换。例如:

  • 默认打开主摄
  • 缩放或低光场景切换到广角或大底 Sensor
  • 支持 dual stream(如主摄+ToF)同时运行

HAL 层封装的策略如下:

  • sensor_controller 模块:管理 sensor enable/disable 状态
  • stream_mapper:根据场景控制 sensor pipeline 的开启关闭
  • AE/AWB 等统计模块进行切换适配
7.3 动态配置与热插拔支持

高可靠性的产品形态需要支持模组热插拔(如 USB 摄像头/外挂模组),HAL 需监测设备 /dev/media* 或 uevent,进行:

  • 重新枚举 sensor node
  • 动态重建 pipeline graph
  • 适配 metadata 输出结构,防止 crash

8. 工程实战调试建议:日志抓取、参数追踪与平台兼容性分析

海思平台调试复杂,尤其是在 HAL 模块与驱动层交互频繁的场景下。以下为核心调试建议与工程路径:

8.1 日志抓取建议
  • 抓取 HAL 关键日志:使用 property set persist.vendor.camera.log.level 3 打开 HAL 日志开关

  • 抓取 sensor/ISP 驱动 log:配置内核 dmesg 关键打印等级(如 [ISP_DBG][DRV_SENSOR]

  • 抓帧工具链

    • 使用 v4l2-dbgmedia-ctl 查看 pipeline
    • 配合 ffmpeg 拉取设备节点帧数据验证格式与流畅性
8.2 参数追踪路径
  • 使用 HAL 打印调试接口追踪 metadata 参数传递路径(如 ae_mode, frame_number)

  • 校验 ioctl 调用时序(通过 tracepoint 或打印钩子):

    • VIDIOC_REQBUFS
    • VIDIOC_STREAMON
    • VIDIOC_QBUF / DQBUF
  • 多帧 debug 建议加入帧序号 log,验证帧同步一致性

8.3 平台兼容性与差异点分析
模块HiSilicon 特性通用平台对比(MTK/QCOM)
Sensor 初始化驱动基于设备树绑定,手动 media-linkMTK/QCOM 多用动态 link 管理
ISP 配置流程固定路径传参至 ISP 包含 AE/AWBQCOM 使用 Tuning Manager,MTK 用 3ATemp
HAL 流切换策略使用 open/close 重启 sensor pipelineQCOM 可通过 CHI HAL 动态挂载
调试接口自研 sensor_debug、ae_debug 接口QCOM 使用 CamXTrace,MTK 有 AAAFlow
8.4 实战建议
  • 多模组系统推荐采用“模块适配表”封装 sensor 参数(Tuning ID、初始化模式、I2C ID)
  • 所有 metadata 建议使用统一封装方式传递至上层(YAML/JSON),便于自动化比对
  • 推荐构建平台适配 abstraction 层,将 sensor/ISP 特有路径解耦

本文转自 https://zhxin.blog.csdn.net/article/details/148668911,如有侵权,请联系删除。