写了很多Camera实战文章,但一直没系统梳理过架构。这篇补上——从V4L2框架到Pipeline/Node体系,从CRM请求管理器到IFE硬件状态机,把Camx的核心架构串一遍。理解了架构,后面的调试和开发才能有的放矢。
一、整体架构:KMD + UMD分层
高通Camera软件架构分为两层:内核态驱动(KMD)和用户态驱动(UMD),两者通过V4L2接口通信。
| | |
|---|
| | Camx Core、CHI Framework、Node |
| | |
| | |
关键设计理念:KMD只负责硬件控制,不做任何图像处理逻辑。Pipeline编排、算法决策全在UMD。这样设计的好处是KMD可以跨平台复用,而UMD可以灵活适配不同产品需求。
二、V4L2框架:Camera的通信基石
V4L2(Video4Linux2)是Linux的视频设备标准框架。高通Camera驱动基于V4L2构建,但做了大量定制。
2.1 V4L2的两层结构
V4L2是两层驱动系统:
- 顶层 videodev 模块:注册为字符设备(major 81),提供统一的V4L2接口
- 底层 subdevice 模块
当UMD需要操作某个Camera硬件时,通过Videodev找到对应的子设备,然后通过IOCTL发送命令。
2.2 Camera子设备清单
开机时,所有Camera硬件组件都会注册为V4L2子设备:
// 开机时子设备注册日志
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-cpas
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-isp
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-cci-driver
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-csiphy-driver
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-actuator-driver
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-sensor-driver
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-flash-dev
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-eeprom
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-ois
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-icp
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-jpeg
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-fd
CAM_INFO: CAM-CRM: cam_register_subdev: v4l2_device_register_subdev sd: cam-lrme2.3 设备分类:实时 vs 非实时
Camera设备按功能分为两类:
| | |
|---|
| | |
| | IPE、JPEG、FD、LRME、Actuator |
这个分类很重要——实时设备通过CRM同步,非实时设备不需要CRM同步。理解这一点,调试帧同步问题时就知道该查哪个链路。
三、CRM:请求管理器
CRM(Camera Request Manager)是KMD中最核心的组件,负责同步所有实时设备的请求应用。
3.1 CRM的核心职责
- 请求同步:确保同一帧的Sensor配置、IFE配置、Flash配置同步生效
- SOF触发:IFE每帧产生SOF中断后通知CRM,CRM决定该帧应用哪个请求
- 请求追踪
- 错误恢复
- Flush处理
3.2 CRM的关键概念:Pipeline Delay
CRM管理请求的核心机制是Pipeline Delay(PD)。不同设备有不同的处理延迟:
// CRM Link时输出的设备Pipeline Delay信息
CAM_DBG: CAM-CRM: connected: cam-isp, id 4, delay 1, trigger 1
CAM_DBG: CAM-CRM: connected: cam-sensor, id 1, delay 2, trigger 1
CAM_DBG: CAM-CRM: connected: cam-actuator, id 3, delay 1, trigger 1
CAM_DBG: CAM-CRM: connected: cam-flash, id 2, delay 1, trigger 1解释:
delay 2:Sensor,需要提前2帧配置(因为Sensor有上电+曝光延迟)delay 1:IFE/Flash/Actuator,提前1帧配置
这意味着:请求N在Sensor上配置后,需要在第N+2帧的SOF时才能生效。CRM就是通过这个PD机制来同步不同设备的配置时序。
3.3 CRM请求处理流程
// CRM在SOF中断时的处理流程
// 1. IFE产生SOF中断,通知CRM
CAM_INFO: CAM-ISP: __cam_isp_ctx_notify_sof_in_activated_state: Start Notify CRM SOF frame 1
// 2. CRM工作队列被唤醒
CAM_DBG: CAM-CRM: cam_req_mgr_workq_enqueue_task: enq task pending_cnt 1
// 3. CRM查找该SOF应该应用的请求
CAM_DBG: CAM-REQ: cam_req_mgr_process_trigger: link_hdl 43010d frame_id 1, trigger 1
// 4. 检查请求就绪状态(pd_mask 6 = 0b110 = pd2+pd1就绪)
CAM_DBG: CAM-CRM: __cam_req_mgr_check_link_is_ready: SOF: idx 0 result 6 pd_mask 6
// 5. 向各设备发送应用请求
CAM_DBG: CAM-REQ: __cam_req_mgr_send_req: SEND: link_hdl: 43010d pd 2 req_id 1
CAM-REQ: cam_sensor_apply_request: Sensor update req id: 1
CAM_DBG: CAM-REQ: __cam_req_mgr_send_req: SEND: link_hdl: 43010d pd 1 req_id 1
CAM-REQ: __cam_isp_ctx_apply_req_in_activated_state: Apply request 1日志中req_id=1:-1:0的格式表示(pd2:pd1:pd0),即pd2设备应用请求1,pd1设备跳过(-1),无pd0设备。
3.4 CRM常见错误
四、IFE/VFE:图像处理引擎
IFE(Image Front End)是Camera硬件的图像处理前端,负责接收Sensor输出的Raw数据并进行实时ISP处理。
4.1 IFE的硬件组成
IFE硬件包含以下主要模块:
- CSID:Camera Serial Interface Decoder,解码MIPI数据
- CAMIF:Camera Interface,接收解码后的数据
- ISP模块
- BUS_IF
4.2 IFE的三层架构
IFE在KMD中分为三层:
| | |
|---|
| | |
| | 处理核心逻辑:SOF通知、配置缓存、Bubble检测 |
| | |
4.3 IFE Context状态机
IFE Context有5个状态,描述了从初始化到工作再到释放的完整生命周期:
IFE Context状态流转:
Uninit → Available → Acquired → Ready → Activated
│ │ │ │ │
│ │ │ │ └─ 主工作状态:处理每帧请求
│ │ │ └─── 等待stream-on命令
│ │ └───── 等待初始配置 + Link
│ └──────── 初始化完成,在free pool中等待acquire
└────────── 构造完成,等硬件probe各状态的关键行为:
- Available:IFE Context已初始化,在free pool中等待被acquire
- Acquired
- Ready
- Activated:主工作状态,处理SOF、配置应用、Bubble检测、BUF_DONE等
4.4 Activated状态的子状态机
进入Activated状态后,IFE还有一套子状态机,由中断驱动:
理解这个子状态机对调试至关重要——当你看到日志中IFE在某个子状态卡住时,就知道该查哪个中断没有按预期到来。
五、CPAS:时钟与总线管理
CPAS(Camera Power and Arbiter System)管理Camera硬件的时钟投票和总线带宽分配。
5.1 CPAS的核心功能
- 时钟投票:各Camera模块需要工作时,通过CPAS申请时钟
- 带宽分配
- 电源域管理
- 资源仲裁
5.2 CAMNOC总线
CAMNOC是Camera专用总线,分为三个通道:
CAMNOC通道划分:
hf1 (High-Frequency 1) → IFE实时数据传输(高带宽低延迟)
hf2 (High-Frequency 2) → IPE/JPEG非实时数据传输
sf1 (Shared-Frequency) → 配置寄存器访问(低带宽)当出现ISP Overflow或带宽不足的问题时,CPAS日志是关键排查入口。
5.3 开启CPAS日志
# 开启CPAS调试日志
adb shell "echo 0x40 > /sys/module/cam_debug_util/parameters/debug_mdl"
# 查看CPAS时钟投票
adb shell "cat /sys/kernel/debug/camera/cpas/cpas_info"
# 查看各模块带宽申请
adb shell "cat /sys/kernel/debug/camera/cpas/bw_info"六、UMD:Pipeline与Node体系
在KMD之上,UMD负责所有Camera业务逻辑。核心概念是Pipeline和Node。
6.1 Pipeline
Pipeline是一条处理流水线,由多个Node串联组成。一个Pipeline的典型结构:
RealtimePreview Pipeline:
SensorNode → IFENode → IPENode → OutputNode(JPEG/Preview/Video)
OfflineSnapshot Pipeline:
IFENode → IPENode → JPEGNode → OutputNode每个Pipeline有自己的Session和Request队列。UMD通过ProcessCaptureRequest接收来自Framework的请求,分发给Pipeline处理。
6.2 Node
Node是Pipeline中的最小处理单元。每个Node有:
- 输入端口
- 处理逻辑:ExecuteProcessRequest方法,处理一帧数据
- 输出端口
- Fence机制
6.3 UMD到KMD的调用链
一个完整的请求从Framework到硬件的调用链:
// 1. Framework发请求到Camx
camxsession.cpp: ProcessCaptureRequest()
→ 添加到请求队列,启动Job
// 2. Camx Pipeline分发请求到各Node
camxpipeline.cpp: ProcessRequest()
→ SensorNode: ApplySensorUpdate()
→ IFENode: ExecuteProcessRequest()
// 3. Node通过CSL提交硬件配置包
camxifenode.cpp: ExecuteProcessRequest()
→ CSLSubmitPacket()
// 4. KMD接收到配置包
cam_req_mgr_cb_add_req() → CRM处理
// 5. CRM在SOF时触发应用
cam_req_mgr_process_trigger()
→ __cam_isp_ctx_apply_req_in_activated_state()
// 6. 硬件配置生效,处理数据
// 7. IFE产出数据,BUF_DONE通知
__cam_isp_ctx_handle_buf_done_in_activated_state()
// 8. UMD收到Fence回调
camxnode.cpp: CSLFenceCallback()
→ SinkPortFenceSignaled()
→ 上报stream done给Framework理解这条调用链,是排查Camera延迟和帧丢失问题的基础。当预览卡顿或帧丢失时,沿着这条链路逐段检查日志,就能定位到卡在哪个环节。
七、架构调试速查表
| | |
|---|
| | acquire_device, probe, power_on |
| | SOF, stream_on, skip_frame |
| | not_ready, open_req, skip |
| | overflow, csid, bus_wr_err |
| | |
| | |
小结
Camx架构的核心可以浓缩为一张图:
┌─────────────────────────────────────────┐
│ Android Camera Framework │
│ (Camera2 API / CameraX) │
├─────────────────────────────────────────┤
│ UMD (Camx + CHI) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Pipeline │→│ Node │→│ Node │ │
│ │Session │ │(IFE/IPE)│ │(JPEG等) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ CSL Interface │
├─────────┼──────────────────────────────────┤
│ │ V4L2 IOCTL │
│ ┌──────▼──────────────────────────────┐ │
│ │ KMD (Kernel Driver) │ │
│ │ │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │ CRM │ │ IFE │ │CPAS │ │ │
│ │ │ │ │/VFE │ │ │ │ │
│ │ └──┬──┘ └──┬──┘ └─────┘ │ │
│ │ │ │ │ │
│ │ ┌──▼──┐ ┌──▼──────────┐ │ │
│ │ │Sensor│ │CSI/ISP/BUS │ │ │
│ │ │Flash │ │Hardware │ │ │
│ │ │OIS │ │ │ │ │
│ │ └─────┘ └─────────────┘ │ │
│ └──────────────────────────────────────┘ │
├─────────────────────────────────────────┤
│ Camera Hardware │
└─────────────────────────────────────────┘理解架构是深度开发的前提。当你遇到问题时,先定位问题发生在哪一层(UMD还是KMD),再定位是哪个模块(CRM还是IFE还是CPAS),最后用对应模块的调试命令深入排查——这就是架构驱动的调试方法论。
更多Camera开发实战内容
欢迎加入知识星球「小驰成长圈」
120+ Camera工程师 · 340+ 实战内容 · 已运营1565天

微信扫码 · 加入星球
评论 (0)