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,一次执行同时收集三层日志,避免反复插拔设备导致状态变化。
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层。
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。
3.5 工具链联合使用实战流程
以下是一个标准排查流程,适用于大部分黑屏场景:
- 准备环境:开启HAL详细日志、清空dmesg环形缓冲区(
adb shell dmesg -c)、启动trace-cmd录制。 - 复现黑屏:打开相机App,等待黑屏出现。
- 停止录制:按顺序停止trace-cmd、保存logcat、导出dmesg。
- 分层分析:
- dmesg:检查是否有
camera_probe失败或I2C错误。 - logcat:搜索
configureStreams返回值、processCaptureRequest超时。 - trace-cmd:计算帧中断间隔,确认是否有调度延迟。
- dmesg:检查是否有
- 输出根因:填写排查报告,明确问题归属层(驱动/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 即可一键收集三层日志,节省重复输入命令的时间。