4. 源码目录结构解析

好,咱们接着往下走。上一章我们把整个HAL源码的顶层结构捋了一遍,这一章我带你钻进 hardware/rockchip 这个核心目录里,看看里面到底藏了些什么宝贝。

说实话,我第一次打开这个目录的时候,也被里面密密麻麻的文件夹吓了一跳。但别慌,咱们一个一个来拆解。我习惯按功能模块来划分,这样思路会清晰很多。

4.1 Camera 模块:图像采集的“眼睛”

Camera 模块,说白了就是负责让摄像头“看见”东西。它位于 hardware/rockchip/camera 下,是整个HAL里最复杂的模块之一。

核心功能: 提供统一的摄像头接口,让上层应用(比如相机App)不用关心底层用的是OV的传感器还是索尼的传感器。

这个目录下主要包含这几个子模块:

  • hal/:Camera HAL 的核心实现。里面封装了 open/close/start_preview/take_picture 等标准接口。我刚开始做的时候,经常在这里面调试 preview 卡顿的问题。
  • libcamera/:一个轻量级的相机库,负责图像数据的流转。嗯,这里要注意,它和 Android 原生的 Camera2 是两码事。
  • sensor_drv/:传感器驱动适配层。不同厂商的 sensor 需要在这里注册自己的配置参数。

个人经验: 我在项目中遇到过最头疼的问题,就是 sensor 的初始化时序。不同 sensor 的上电时序、MCLK 频率要求都不一样。我建议你在调试新 sensor 时,先用示波器把这几路信号抓出来看看,能省不少时间。

4.2 Display 模块:图像输出的“窗口”

Display 模块负责把图像数据送到屏幕上。路径是 hardware/rockchip/display。这个模块我印象很深,因为当年调双屏异显的时候,差点没把我整崩溃。

它的核心组件包括:

子模块 功能说明
hwcomposer 硬件合成器,负责把多个图层合成一帧画面
gralloc 图形缓冲区分配器,管理显存
libdisplay 显示核心库,封装了EDID解析、分辨率切换等
lights 背光控制,包括LCD背光和LED指示灯

你想想看,一个屏幕要显示相机预览画面、系统状态栏、还有你手指滑动的轨迹,这些图层怎么叠在一起?就是靠 hwcomposer 来搞定的。

避坑指南: 我曾经在调试4K输出时,发现画面总是撕裂。查了两天才发现是 gralloc 分配的 buffer 对齐方式不对。记住,RK3588 的 VPU 要求 buffer 按 64 字节对齐,少一点都不行。

4.3 Audio 模块:声音的“耳朵”和“嘴巴”

Audio 模块在 hardware/rockchip/audio 下。说实话,音频调试比视频更玄学,因为很多问题靠眼睛看不出来,只能靠耳朵听。

这个目录的结构相对清晰:

  • primary/:主音频设备 HAL,负责播放和录音
  • usb/:USB 音频设备支持
  • policy/:音频策略配置,比如插耳机时自动切换通道
  • libtinyalsa/:精简版 ALSA 库,瑞芯微自己封装的

我个人习惯在调试音频问题时,先检查 tinyalsa 的 mixer 节点。很多杂音问题,其实就是某个 mixer 控件的增益没设对。

4.4 Sensor 模块:感知世界的“神经末梢”

这里的 Sensor 不是摄像头传感器,而是指加速度计、陀螺仪、磁力计这些。路径是 hardware/rockchip/sensor。

它包含:

  • libsensor/:传感器 HAL 核心库
  • sensor_hal/:具体传感器的 HAL 实现
  • calibration/:传感器校准算法

为什么需要校准?你想想看,一个加速度计在静止状态下,理论上三轴输出应该是 (0, 0, 9.8)。但实际芯片总有偏差,不校准的话,你的计步器可能走两步就算一万步了。

4.5 其他重要子模块

除了上面四个大头,还有几个模块也值得关注:

模块 路径 一句话说明
Codec hardware/rockchip/codec 硬件编解码器,支持 H.264/H.265/VP9 等
GPS hardware/rockchip/gps GPS 定位 HAL,支持北斗和 GLONASS
IR hardware/rockchip/ir 红外遥控驱动,很多机顶盒方案用这个
Wifi hardware/rockchip/wifi Wi-Fi 和蓝牙的 HAL 封装

小技巧: 如果你在移植新硬件,建议先从 hardware/rockchip 里找一个最接近的参考实现,复制一份再改。瑞芯微的工程师们已经帮你踩过很多坑了,别自己从头造轮子。

4.6 模块间的协作关系

这些模块不是孤立的。举个例子,相机预览的画面要显示在屏幕上,Camera 模块把数据送到 Display 模块,Display 模块再通过 hwcomposer 合成输出。中间还可能经过 Codec 模块做编码,存成视频文件。

下面这张图,是我画的一个简化版协作流程:

hardware/rockchip 模块协作关系图 Camera 模块 图像采集 Display 模块 图像输出 Audio 模块 音频处理 Sensor 模块 传感器数据 Codec 模块 编解码 应用层 App / Framework 预览数据 画面输出 传感器事件 音频流 编码/解码 图例说明: Camera Display Audio Sensor Codec 应用层 数据流 双向/可选流

你看,Camera 采集的数据可以直接给 Display 做预览,也可以给 Codec 做编码存文件。Sensor 的数据则直接上报给应用层。Audio 是独立的音频通道,但播放视频时它要和 Display 同步。