第二章 开发环境搭建与调试工具链
做高通ISP调试,说白了就是两件事:把环境搭对,把工具用熟。我见过太多工程师,问题定位到一半发现log没开、raw图没dump、工具链版本不匹配——白白浪费一整天。这一章,我把这些年踩过的坑和积累的习惯一次性讲清楚。
2.1 高通QPST/QXDM:芯片调试的“听诊器”
QPST(Qualcomm Product Support Tool)和QXDM(Qualcomm eXtensible Diagnostic Monitor)是高通平台最底层的调试工具。我个人习惯把QPST比作“手术刀”,QXDM比作“听诊器”——一个用来改,一个用来听。
2.1.1 QPST核心功能
| 功能模块 | 用途 | 我常用的场景 |
|---|---|---|
| EFS Explorer | 浏览/修改手机文件系统 | 替换ISP tuning参数、校准文件 |
| Software Download | 烧录固件、分区镜像 | 刷不同版本的camera驱动 |
| NV Browser | 读写NV(Non-Volatile)项 | 修改sensor ID、EEPROM配置 |
| Memory Debug | 内存转储、寄存器读写 | 定位ISP pipeline hang死问题 |
2.1.2 QXDM日志抓取
QXDM是抓取高通芯片内部消息的利器。它不依赖Android系统,哪怕系统卡死在boot阶段,QXDM照样能抓到modem和DSP的log。
我一般这样配置:
- 手机进入Diag模式(通常拨号盘输入
*#*#717717#*#*) - USB连接电脑,设备管理器出现“Qualcomm HS-USB Diagnostics”端口
- QXDM选择对应COM口,波特率设为921600(默认115200太慢,高帧率场景会丢log)
- 在View → Log窗口勾选
ISP、CAMERA、SENSOR相关log mask
// QXDM常用过滤关键字(我自己的收藏)
ISP_ERR
CAMIF_ERROR
SENSOR_I2C_FAIL
CPP_HANG
IPE_TIMEOUT
2.2 CamX/Chi架构:理解ISP的“骨架”
CamX是高通从Android 9开始推的camera HAL架构,Chi(Camera Hardware Interface)是它的插件化扩展层。说白了,CamX是框架,Chi是积木。
2.2.1 架构分层
2.2.2 关键文件与路径
调试时最常打交道的几个文件:
| 文件/路径 | 说明 | 调试价值 |
|---|---|---|
camxhal3.cpp |
CamX HAL3入口 | 看request流转、session创建 |
chi*.cpp |
Chi节点实现 | 定位vendor算法挂死 |
camxnode.cpp |
pipeline node基类 | 查node状态机异常 |
camxstats.cpp |
3A统计信息 | AE/AF/AWB异常排查 |
chi_oem.xml |
OEM定制配置文件 | sensor/ISP tuning参数 |
Node::WaitForDependency 超时,八成是某个node处理太慢,堵住了下游。
2.3 ADB调试:最常用的“瑞士军刀”
ADB(Android Debug Bridge)大家都会用,但ISP调试有它特殊的用法。我总结了一套“三板斧”:
2.3.1 三板斧之一:dumpsys camera
# 查看camera服务状态
adb shell dumpsys camera
# 只看某个cameraId的session信息
adb shell dumpsys camera | grep -A 50 "Camera 0"
# 查看stream配置
adb shell dumpsys camera | grep -E "Stream|Format|Size|Usage"
这个命令能告诉你:当前有几个session、每个session的stream配置、buffer状态、pending request数量。我遇到“拍照黑屏”问题时,第一件事就是跑这个命令,看stream有没有成功创建。
2.3.2 三板斧之二:setprop 控制开关
# 开启CamX详细log(我调试必开)
adb shell setprop persist.vendor.camera.logs 0x1F
# 开启Chi log
adb shell setprop persist.vendor.camera.chi.logs 0x1F
# 强制dump每一帧的raw图(调试HDR合成时用过)
adb shell setprop persist.vendor.camera.rawDump 1
# 关闭3A,固定曝光(测sensor线性度)
adb shell setprop persist.vendor.camera.3A.disable 1
persist. 开头的属性重启后仍然生效。我曾经在客户现场开了rawDump忘记关,结果手机用半天就提示存储空间不足——raw图一张几十MB,拍4K视频每秒就写几百MB。调试完记得 adb shell setprop persist.vendor.camera.rawDump 0。
2.3.3 三板斧之三:tombstone 与 crash 分析
# 抓取camera service crash的tombstone
adb pull /data/tombstones/
# 查看camera provider的crash log
adb logcat -b crash | grep -i camera
# 查看native crash的backtrace
adb shell dmesg | grep -i "camera\|ISP"
我遇到过一种情况:camera app闪退,但logcat里没有任何error。后来查tombstone才发现是Chi node里一个空指针——vendor算法传了个null buffer进来。这种问题,光看logcat是看不出来的。
2.4 dump raw图:ISP调试的“X光片”
raw图是sensor输出的原始数据,没经过ISP任何处理。看raw图就像医生看X光片——能直接看到sensor本身的问题,还是ISP处理的问题。
2.4.1 如何dump raw图
方法一:通过ADB命令(最常用)
# 开启raw dump
adb shell setprop persist.vendor.camera.rawDump 1
# 拍照或录像,raw图会保存在 /data/vendor/camera/raw/
adb shell ls /data/vendor/camera/raw/
# 拉取到电脑
adb pull /data/vendor/camera/raw/ ./raw_dump/
方法二:通过QXDM的Memory Debug窗口,直接读取ISP寄存器中的raw buffer地址。这个方法适合抓某一帧的raw,不影响正常流程。
2.4.2 raw图分析工具
| 工具 | 用途 | 我的评价 |
|---|---|---|
| RAW2RGB(高通官方) | 将raw转为可预览的RGB图 | 简单快速,但只能看个大概 |
| dcraw / libraw | 命令行raw解析 | 适合批量处理,脚本化分析 |
| Python + numpy | 自定义分析(坏点、噪声、线性度) | 我最常用的方式,灵活 |
| MATLAB Image Toolbox | 专业图像质量分析 | 做IQ报告时用,太重 |
2.5 logcat抓取ISP日志:定位问题的“第一现场”
logcat是Android最直接的日志输出通道。但ISP相关的log默认是关闭的——因为太频繁了,一秒钟几百条,开了手机会卡。
2.5.1 开启ISP log的正确姿势
# 1. 开启所有camera相关log(级别从低到高)
adb shell setprop persist.vendor.camera.logs 0x1F
# 2. 重启camera provider(不用重启手机)
adb shell killall cameraserver
# 3. 抓取过滤后的log
adb logcat -v threadtime | grep -E "camx|chi|ISP|Sensor" > isp_log.txt
log级别定义(0x1F = 全部开启):
| Bit位 | 级别 | 内容 |
|---|---|---|
| Bit 0 | Error | 致命错误,必须看 |
| Bit 1 | Warning | 潜在问题,建议看 |
| Bit 2 | Info | 关键流程信息 |
| Bit 3 | Verbose | 详细调试信息(慎开) |
| Bit 4 | Perf | 性能统计 |
2.5.2 常见log模式与解读
我总结了几种典型的log模式,看到就能猜个八九不离十:
- 反复出现
Flush/Abort→ 大概率是app端反复打开关闭camera,检查app逻辑 Node::WaitForDependency超时 → 某个node处理太慢,查对应node的算法耗时Buffer underrun→ ISP的输入buffer不够,检查sensor输出帧率I2C transfer failed→ sensor寄存器读写失败,查硬件连接或sensor驱动HAL: configureStreams failed→ stream配置不合法,查分辨率/格式组合
adb logcat -v threadtime | grep -E "camx|chi" > camx_$(date +%Y%m%d_%H%M%S).log,然后才去复现问题。这样log文件带时间戳,方便回溯。调试完立刻关掉,别让log一直写——我吃过手机存储写满的亏。
2.6 本章小结
工具链这东西,光看文档是学不会的。你得亲手搭一遍环境,亲手抓一次log,亲手看一张raw图,才能理解每个工具在什么场景下用。我建议你:
- 找一台高通平台的手机,按本章步骤把QPST/QXDM连上
- 在CamX代码里加几行自己的log,编译烧录,看能不能抓到
- 拍一张raw图,用Python读出来,看看bayer pattern长什么样