1. RK平台Camera驱动调试概述

各位好,我是老周。做RK平台Camera驱动有些年头了,踩过的坑不少,积累的经验也还行。今天咱们开始这门课,先把这个领域的底子打扎实。

这一章,我打算从四个角度切入:RK平台的Camera子系统长什么样、MIPI CSI-2协议到底在传什么、V4L2框架怎么管住摄像头,以及调试环境怎么搭、工具链怎么配。说白了,就是先让你对整个体系有个全局感,后面遇到具体问题才知道往哪个方向查。

1.1 RK平台Camera子系统架构

先看整体。RK平台的Camera子系统,我习惯把它分成三层:物理层、控制器层和软件框架层。

  • 物理层:Sensor模组、MIPI走线、时钟、电源。这一层出问题,画面要么全黑,要么花屏。
  • 控制器层:RK自家的ISP(图像信号处理器)、MIPI D-PHY控制器、CSI-2 Host。这一层负责把原始数据转成可用的图像格式。
  • 软件框架层:V4L2驱动、Media Controller拓扑、用户态应用(如Camera HAL)。这一层决定了上层怎么调用底层。

我记得刚接手RK3588项目时,看到它的ISP模块支持三路MIPI同时输入,心里还挺兴奋的。但实际调试时发现,三路Sensor的同步问题折腾了我整整两周。嗯,这个后面会细讲。

核心要点:RK平台的Camera驱动调试,本质上就是在这三层之间来回定位问题。物理层看波形,控制器层看寄存器,软件层看log和调用链。

下面这张图,是我自己整理的RK Camera子系统数据流。你仔细看看,数据从Sensor出来,经过MIPI、ISP,最后到V4L2设备节点,每一步都有对应的调试手段。

RK平台Camera子系统数据流 Camera Sensor MIPI D-PHY CSI-2 Host ISP V4L2 Device Media Controller Camera HAL App / Framework 调试关注点: • Sensor端:I2C通信、时钟、电源、初始化序列 • MIPI端:D-PHY电压、时钟频率、LP/HS模式切换 • ISP/V4L2端:格式协商、buffer管理、中断处理

1.2 MIPI CSI-2协议基础

MIPI CSI-2,说白了就是摄像头和处理器之间的“普通话”。它规定了数据怎么打包、怎么传输、怎么解析。

我个人觉得,理解CSI-2协议,抓住三个概念就够了:Lane、Data Type和帧结构。

概念 说明 调试中常见问题
Lane 数据通道,1/2/4 Lane常见。Lane数越多,带宽越大。 Lane分配错误导致无数据或数据错位
Data Type 标识数据类型,如RAW10、YUV422、JPEG等。 DT不匹配导致ISP解析失败,画面偏色
帧结构 每帧数据由FS(帧起始)、Line数据、FE(帧结束)组成。 帧同步丢失导致画面撕裂或卡死
我的经验:调试MIPI信号时,先用示波器看D-PHY的LP-00、LP-01状态切换是否正常。如果LP状态都不对,后面全是白搭。我曾经在一个项目里,因为Sensor的MIPI端接电阻焊错了,导致LP状态一直卡在00,查了三天才找到原因。

CSI-2的传输模式分两种:LP(低功耗)模式和HS(高速)模式。LP模式用于控制信号,HS模式用于传输图像数据。你想想看,如果HS模式起不来,画面就是黑的;如果LP模式不稳定,Sensor可能根本不被识别。

1.3 V4L2框架简介

V4L2,全称Video for Linux 2,是Linux内核里管理视频设备的框架。RK平台的Camera驱动,本质上就是写一个V4L2子设备驱动,挂到Media Controller拓扑里。

我刚开始学V4L2时,被它那一堆ioctl搞得晕头转向。后来总结出一个规律:V4L2的核心就是“打开设备 → 查询能力 → 设置格式 → 申请buffer → 入队出队 → 处理数据”这个循环。

下面这个表格,列出了V4L2驱动里最关键的几个ioctl,以及它们对应的调试要点:

ioctl 作用 调试要点
VIDIOC_QUERYCAP 查询设备能力 确认driver版本、capabilities标志位
VIDIOC_S_FMT 设置图像格式 检查width/height/pixelformat是否被正确接受
VIDIOC_REQBUFS 申请buffer 确认buffer数量、大小、类型(MMAP/USERPTR/DMABUF)
VIDIOC_QBUF 入队buffer 检查buffer状态是否变为QUEUED
VIDIOC_DQBUF 出队buffer 检查timestamp、bytesused、flags
VIDIOC_STREAMON 启动流 确认中断是否产生,DMA是否开始搬运
注意:V4L2的buffer管理是驱动调试的重灾区。我曾经遇到过一个问题:上层应用调用QBUF后,驱动没有正确设置buffer的m.offset,导致DMA写到了错误的内存地址,画面全是噪点。这个问题查了整整两天,最后用printk打印buffer物理地址才定位到。

1.4 调试环境搭建与工具链准备

工欲善其事,必先利其器。调试Camera驱动,环境搭不好,后面寸步难行。

我个人的习惯是,准备三样东西:硬件调试工具、软件调试工具和内核配置。

硬件调试工具

  • 示波器:至少4通道,200MHz以上带宽。用来抓MIPI时钟、数据线、I2C信号。
  • 逻辑分析仪:调试I2C通信时特别好用。我习惯用Saleae,便宜又好用。
  • 串口线:UART输出内核log,这是最基本的。

软件调试工具

  • v4l2-ctl:V4L2用户态工具,可以查询设备、设置格式、抓图。
  • media-ctl:Media Controller工具,查看和配置拓扑。
  • yavta:测试V4L2视频采集的工具,支持各种格式和buffer模式。
  • trace-cmd / kernelshark:跟踪内核函数调用,调试驱动流程。

内核配置要点

编译内核时,记得打开以下选项:

CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF2_CORE=y
CONFIG_VIDEOBUF2_DMA_CONTIG=y
CONFIG_VIDEO_ROCKCHIP=y
CONFIG_VIDEO_ROCKCHIP_ISP=y
CONFIG_VIDEO_ROCKCHIP_CSI=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_V4L2_FWNODE=y
避坑指南:我曾经因为忘记打开CONFIG_VIDEOBUF2_DMA_CONTIG,导致申请buffer时一直返回-ENOMEM。这个选项在RK平台上必须开,因为ISP需要连续的物理内存。

好了,这一章的内容就到这里。你先把这些基础概念和环境准备好,后面我们就要开始真刀真枪地调试了。