3、黑屏排查工具链:adb logcat抓取HAL日志、dmesg查看驱动错误、trace-cmd分析时序

黑屏问题的根因往往隐藏在多个软件层的交叉点:HAL层日志丢失、驱动层报错被忽略、或者时序竞争导致帧数据未送达。本章构建一套三层排查工具链,分别对应日志、驱动、时序三个维度,帮助工程师在5分钟内完成初步根因定位。

排查原则:先看驱动(dmesg)排除硬件/电源异常,再查HAL日志(logcat)确认流状态,最后用时序工具(trace-cmd)定位帧边界。切忌跳过驱动层直接分析HAL日志。

3.1 工具链全景与分工

三种工具在排查链路中的角色与数据来源如下表所示:

工具 数据来源 排查目标 典型命令
adb logcat HAL进程(cameraserver、vendor.qti.camera) 流创建失败、buffer超时、参数校验错误 adb logcat -s CameraHal:V
dmesg 内核驱动(camera sensor、CCI、ISP) I2C通信错误、电源域未上电、中断丢失 adb shell dmesg | grep -i cam
trace-cmd 内核ftrace事件(sched_wakeup、camera_irq) 帧中断延迟、buffer提交时序、CPU迁移 trace-cmd record -e camera*
工程建议:将三条命令封装为一个shell脚本 cam_diag.sh,一次执行同时收集三层日志,避免反复插拔设备导致状态变化。
黑屏排查三层工具链架构 黑屏排查三层工具链架构 黑屏 / 无帧 adb logcat HAL日志 · 流状态 · 参数错误 dmesg 驱动错误 · I2C · 电源域 trace-cmd ftrace · 帧中断 · 时序分析 根因判定 驱动异常 / HAL超时 / 时序竞争 排查顺序: ① dmesg 排除驱动层错误 → ② logcat 检查HAL流状态 → ③ trace-cmd 分析帧时序 每层确认无异常后再进入下一层,避免被噪声日志误导。

3.2 adb logcat:HAL日志抓取与过滤

HAL日志是黑屏排查的第一手资料。关键日志标签与排查要点如下:

  • 标签过滤:使用 -s CameraHal:V 或 -s CamX:V(高通平台),避免被系统日志淹没。
  • 关键关键字:configureStreams、processCaptureRequest、buffer_status、ERROR、timeout。
  • 时间戳对齐:使用 -v threadtime 输出线程ID和时间,便于与trace-cmd关联。
# 抓取HAL详细日志并保存到本地
adb logcat -v threadtime -s CameraHal:V CamX:V > hal_log.txt

# 实时过滤黑屏相关错误
adb logcat -s CameraHal:V | grep -E "ERROR|timeout|configureStreams failed"
常见陷阱:部分平台HAL日志默认等级为INFO,需要手动开启VEBOSE:adb shell setprop persist.vendor.camera.logs 1,然后重启cameraserver。

3.3 dmesg:驱动层错误快速定位

驱动层错误通常表现为I2C通信失败、电源域未就绪或中断未触发。dmesg日志量较大,需要精准过滤:

错误模式 dmesg关键字 可能根因
I2C传输失败 i2c transfer error、NACK sensor电源未上电、硬件地址错误
电源域异常 regulator enable failed、power up fail PMIC配置错误、电压阈值不匹配
中断丢失 irq timeout、no irq GPIO复用冲突、中断控制器配置错误
时钟异常 clk enable failed、mclk off 时钟树未初始化、频率超出范围
# 实时监控驱动错误
adb shell dmesg -w | grep -E "camera|sensor|cci|isp|mclk"

# 查看历史错误并统计出现次数
adb shell dmesg | grep -i "camera" | sort | uniq -c | sort -rn
工程技巧:在dmesg中搜索 camera_probe 确认sensor是否成功枚举。如果probe失败,黑屏排查到此结束,无需继续分析HAL层。
dmesg驱动错误排查流程 dmesg驱动错误排查流程 dmesg | grep camera probe成功? 检查硬件/电源 grep i2c/regulator/irq 定位到具体驱动模块并修复 probe失败直接返回硬件问题;probe成功则按i2c→电源→中断顺序排查

3.4 trace-cmd:帧时序与中断延迟分析

当驱动和HAL日志均无显式错误时,黑屏往往由时序竞争引起。trace-cmd基于ftrace,可以捕获内核事件的时间戳,精确到微秒级。

3.4.1 常用trace事件

事件类别 事件名称 排查用途
camera camera_irq、camera_frame_done 帧中断到达时间、帧间隔
sched sched_wakeup、sched_switch HAL线程是否被调度、CPU迁移
workqueue workqueue_execute_start 驱动workqueue延迟
irq irq_handler_entry、irq_handler_exit 中断处理耗时
# 录制30秒camera相关trace
adb shell trace-cmd record -e camera* -e sched_wakeup -e irq_handler* -o /data/trace.dat sleep 30

# 拉取到本地分析
adb pull /data/trace.dat .

# 使用kernelshark图形化查看(推荐)
kernelshark trace.dat

# 命令行查看帧中断间隔
trace-cmd report trace.dat | grep "camera_frame_done" | head -20

3.4.2 时序分析关键指标

  • 帧中断间隔:正常应为33ms(30fps)或16.6ms(60fps)。间隔波动超过±5ms说明帧率不稳。
  • 中断到buffer提交延迟:HAL收到中断后应在1ms内提交新buffer,超过5ms说明调度阻塞。
  • CPU迁移次数:HAL线程频繁在不同CPU核心间迁移会导致cache miss,增加延迟。
实战案例:某项目黑屏时dmesg和logcat均无错误,trace-cmd发现camera_frame_done中断间隔从33ms跳变到66ms,进一步定位到sched_wakeup事件显示HAL线程被优先级更高的音频线程抢占,导致buffer提交延迟一帧。修复方案:将camera线程优先级提升至SCHED_FIFO:10。
trace-cmd时序分析关键指标 trace-cmd时序分析关键指标 帧中断间隔 正常:33ms (30fps) 异常:>38ms 或 <28ms 中断→buffer延迟 正常:<1ms 异常:>5ms 调度阻塞 CPU迁移次数 正常:<10次/秒 异常:>50次 cache miss 定位时序竞争根因 三个指标联合分析:帧中断间隔异常 → 检查中断→buffer延迟 → 再检查CPU迁移是否导致调度延迟

3.5 工具链联合使用实战流程

以下是一个标准排查流程,适用于大部分黑屏场景:

  1. 准备环境:开启HAL详细日志、清空dmesg环形缓冲区(adb shell dmesg -c)、启动trace-cmd录制。
  2. 复现黑屏:打开相机App,等待黑屏出现。
  3. 停止录制:按顺序停止trace-cmd、保存logcat、导出dmesg。
  4. 分层分析:
    • dmesg:检查是否有 camera_probe 失败或I2C错误。
    • logcat:搜索 configureStreams 返回值、processCaptureRequest 超时。
    • trace-cmd:计算帧中断间隔,确认是否有调度延迟。
  5. 输出根因:填写排查报告,明确问题归属层(驱动/HAL/时序)。
# 一键收集脚本示例(cam_diag.sh)
#!/bin/bash
echo "=== 开始收集黑屏排查日志 ==="
adb shell dmesg -c > /dev/null  # 清空旧日志
adb shell trace-cmd record -e camera* -e sched_wakeup -o /data/trace.dat &
TRACE_PID=$!
adb logcat -v threadtime -s CameraHal:V > hal_log.txt &
LOGCAT_PID=$!
sleep 5  # 等待用户复现
kill $TRACE_PID $LOGCAT_PID
adb shell dmesg > dmesg_log.txt
adb pull /data/trace.dat .
echo "=== 收集完成,请分析 hal_log.txt / dmesg_log.txt / trace.dat ==="
效率提升:将上述脚本加入 ~/.bashrc 别名,每次排查只需执行 cam_diag 即可一键收集三层日志,节省重复输入命令的时间。