2. 开发环境与调试工具链
Snapdragon Camera 的底层工程建立在 Qualcomm 的 Android BSP 之上,代码、编译、调试三者环环相扣。本节围绕“拿到代码—编出镜像—连上设备—抓到日志—定位崩溃”这条主线,把工具链的关键入口讲清楚,让你在遇到 camx 报错或相机进程崩溃时知道从哪里下手。
一、代码获取:从 QCM 到本地仓库
高通平台代码通常通过 CodeAurora(QCM) 或厂商提供的 manifest 仓库获取。典型做法是使用 repo 工具同步:
repo init -u git://codeaurora.org/platform/manifest.git \
-b release -m LA.UM.9.12.r1-08000-SMxx0.0.xml
repo sync -j8 --no-tags
其中 -b 指定分支,-m 指定 manifest 文件,决定了 BSP 版本、内核版本与 camx 版本。相机相关代码主要分布在:
vendor/qcom/proprietary/camx/:CAMX 核心框架与 HAL 实现;vendor/qcom/proprietary/chi-cdk/:CHI 扩展、用例与 OEM 定制;hardware/qcom/camera/:HAL 接口与适配层;device/qcom/<target>/:目标板配置、相机 sensor 与 EEPROM 配置。
同步完成后,建议先确认 camx 与 chi-cdk 的版本号是否与 manifest 一致,避免后续编译出现接口不匹配。
二、编译系统:Soong 与 Make 的混合
Android 10 之后,高通平台编译以 Soong(Android.bp) 为主,Make(Android.mk) 为辅。相机模块的编译入口通常在 camx/Android.mk 与 chi-cdk/Android.mk 中,通过 mm 或 mmm 单独编译:
source build/envsetup.sh
lunch qssi-userdebug
mmm vendor/qcom/proprietary/camx
mmm vendor/qcom/proprietary/chi-cdk
编译产物主要是 camera.qcom.so、com.qti.chi.override.so 等动态库,最终打包进 vendor.img。若只改 camx 代码,可用 adb push 直接替换设备上的 so 文件,再 adb shell sync 并重启相机服务,能显著缩短验证周期。
userdebug 版本,它保留了 root 与 log 权限,同时性能接近 user 版本。三、adb 与 root 调试
adb 是连接设备与主机的桥梁。常用命令包括:
adb devices
adb root
adb remount
adb shell
adb logcat -b all -v threadtime > camx.log
adb pull /data/vendor/camera/
adb root 让 adbd 以 root 运行,adb remount 把 /system、/vendor 重新挂载为可写,便于替换 so 或配置文件。相机相关日志默认输出到 logcat 的 camx、CHI、mm-camera 等 tag,可用 adb logcat -s camx:* CHI:* 过滤。
四、camx 日志与 tombstone 分析入口
CAMX 日志分为 logcat 实时日志 与 离线日志。实时日志通过 CAMX_LOG 宏输出,级别由 camxsettings.xml 中的 LogInfoMask 控制。离线日志则写入 /data/vendor/camera/,常见文件有:
camx.log:CAMX 框架运行日志;chi.log:CHI 扩展层日志;tombstone_00:native 崩溃现场,含 backtrace、寄存器与内存映射。
当相机进程崩溃时,系统会在 /data/tombstones/ 生成 tombstone 文件。分析入口是 debuggerd 与 ndk-stack:
adb shell ls /data/tombstones/
adb pull /data/tombstones/tombstone_00
ndk-stack -sym out/target/product/<target>/symbols/ \
-dump tombstone_00
通过 backtrace 中的函数名与偏移,结合 camx 的符号表,可以定位到具体模块,例如 CamX::Node::ProcessRequest 或 Chi::Pipeline::Execute。若日志中出现 SIGSEGV 且地址为 0x0,通常是空指针解引用;若为 SIGABRT,则多为断言失败或 CHECK 触发。
五、实战判断:从日志到根因
假设相机启动后黑屏,logcat 中反复出现 CamX: [ERROR] Node::ProcessRequest: Invalid node,同时 chi.log 显示 pipeline 创建失败。此时应优先检查 chi-cdk 中对应 usecase 的 XML 配置是否与 sensor 匹配,而不是直接怀疑 HAL。若 tombstone 显示崩溃在 libc.so 的 abort,则向上找 __assert2 的调用者,通常能定位到某个 CAMX_ASSERT 或 CHX_ASSERT。
adb shell sync,否则可能因文件未落盘导致行为不一致;同时注意 vendor 分区在 remount 后重启会恢复,需重新 push。掌握这条工具链后,你就能在代码、编译、设备、日志四个环节之间快速切换,把“相机不工作”这类模糊问题收敛到具体的函数、配置或断言上,为后续深入 CAMX 架构与 CHI 扩展打下基础。