高通平台Sensor调试:QXDM抓ADSP日志与QsensorTest实战技巧
发布时间:2026/9/28 17:57:50 作者:尧图编辑部 阅读量:1,286

做高通平台Sensor调试的兄弟应该都有过这种经历上层Framework数据不对拿着HAL层的log翻来覆去看了半天寄存器配置、I2C读写全检查了一遍芯片型号、中断脚、供电也没问题但问题就是复现着。折腾到最后旁边的老工程师瞥了一眼说“你去抓一下ADSP日志看看”你才意识到Sensor的数据路径根本不只是HAL层到Framework这一段真正干活的是ADSP里面的SLPI核而他的日志才是定位问题的最后一公里。这篇不聊理论就是把我在项目里用QXDM抓ADSP日志、配合QsensorTest验证Sensor问题时的几个关键技巧和踩过的坑写出来。如果你正在做高通平台的Sensor驱动、或者被算法上报、onChange触发这类问题折磨这几个技巧应该能帮你少走不少弯路。1. 先搞清楚Sensor调试为什么要看ADSP日志很多刚接触Sensor的朋友有个误区以为Sensor驱动写好了、HAL层能读到数据问题就是在Framework或者App层。这在功能机或者低端方案上可能成立但高通平台完全是另一套逻辑。1.1 Sensor数据路径的架构拆解在高通平台上物理SensorProximity、Accel、Gyro等通过I2C/SPI挂到AP侧但真正控制Sensor寄存器、跑算法、做数据融合的不是AP的Application Processor而是ADSPAudio Digital Signal Processor内部的SLPISensor Low Power Island核。数据流大概是这样的物理Sensor → I2C/SPI → Linux Kernel Sensor驱动仅做配置和中断处理 → ADSP SLPI核Sensor算法、数据融合、事件检测 → QMI/SSI接口 → Sensor HAL层 → Android Framework所以你在HAL层看到的sensor数据是ADSP算完之后吐出来的结果不是Sensor芯片的原始读数。这意味着什么呢意味着很多疑难杂症——数据漂移、onChange事件不触发、温漂导致的自测失败、休眠唤醒后数据异常——根源大概率藏在ADSP/SLPI这一层而HAL层的log根本看不到这些内部状态。1.2 什么场景下必须动ADSP日志根据我的实际项目经验下面这几类问题你直接在HAL层查基本属于浪费时间问题现象HAL层表现真正可疑的位置Sensor偶发无数据/数据断流HAL层log显示QMI超时或SSI连接异常ADSP进程崩溃或Sensor算法卡死Proximity事件不触发或延迟HAL层能看到校准数据但事件不判定ADSP内部的sensor算法状态机出问题温漂、自测Self Test失败HAL层返回SNS_ERROR或结果异常ADSP中sensor自测逻辑、校准参数保存休眠唤醒后Sensor工作异常唤醒后有数据但质量差ADSP电源管理、Sensor寄存器恢复流程多Sensor融合数据跳变每个Sensor单独看都正常ADSP的sensor fusion算法或时钟同步问题这些场景的共同点是问题发生在ADSP内部常规手段只能看到“结果异常”看不到“为什么异常”。这时候只有把ADSP日志完整拉出来看SLPI核里Sensor算法、Sensor状态机、QMI通信这些层面的流转过程才能定位到根因。2. QXDM抓ADSP日志的正确姿势端口选择和基础配置QXDM这个工具用的人多但真正用得好的不多。抓ADSP日志第一步不是点“Start”而是先确认你连对了端口、选对了过滤器否则后面抓到的东西要么为空、要么被海量无关日志淹没。2.1 端口连不对日志全是空的ADSP日志走的是DIAG口不是普通的USB调试口。很多人第一次抓设备连上后QXDM直接显示Connected就开抓了结果日志列表空空如也还以为Sensor没log输出。我踩过的坑是这样的现在不少调试板或量产机USB口是多路复用状态同一个物理端口可能同时映射了modem的DIAG口、ADSP的DIAG口、还有普通的ADB口。如果你连的是modem那一路ADSP日志当然什么都抓不到。正确做法是设备进入DIAG模式用QXDM菜单栏的Options → Communications → Target Port选择设备节点。如果设备映射了多个DIAG口不要凭感觉选看设备管理器里的端口描述或者用高通工具链的端口探测工具确认哪一路是ADSP/QDSP6。在QXDM里连接到目标端口后用View → QDSP6 Logs打开ADSP日志窗口先随便操作一下Sensor比如用手遮挡Proximity看窗口里有没有输出。这里有个小经验刚连上时如果日志窗口是空的别急着怀疑配置先把手机的传感器转一转、动一动人为制造一点数据流。如果还是没有输出再检查端口而不是反复重新插拔。2.2 MVP配置保存一套常用的抓取配置文件QXDM的过滤器配置是个记忆负担很重的东西每次重新配置一遍既浪费时间又容易漏掉关键项。我的习惯是在干净的环境下一次性配好然后导出保存为配置文件.qcf后续项目直接Load。我常用的配置包括在Log Filters里把Sensor相关的模块过滤项全部勾上重点是SNSSensor Network Stack、SNS_ALGOSensor算法、SNS_SMGRSensor Manager、SNS_SSISensor Stream Interface这几个模块。ADSP日志的级别设置为Medium或Verbose因为很多Sensor问题只在Verbose级别才打印详细的Sensor状态机流转信息默认级别会丢掉关键内容。打开Event Log记录QXDM切换状态、复位、断连等底层事件这在排查ADSP崩溃问题时有奇效。这套配置文件里我还会额外把APRAsynchronous Packet Router日志打开因为SLPI和AP侧HAL通信用的是QMI而QMI底层走APR。遇到QMI超时、SSI断链这类问题时APR层的日志能直接告诉我们QMI消息有没有到达ADSP。3. QsensorTest验证Sensor功能不只会看数据流QsensorTest是高通提供的Sensor诊断工具大多数人拿它来验证Sensor是否出数、校准是否通过。但实际调试中它的价值远不止于此尤其是配合QXDM的日志抓取能形成一套完整的验证闭环。3.1 QsensorTest的基本验证逻辑QsensorTest连接设备后会列出当前平台上的所有Sensor每个Sensor都可以单独打开数据流显示实时数据曲线。它验证的不只是“有没有数据”而是Sensor从底层到HAL层整条链路是否健康打开某个Sensor的数据流能看到数据更新说明从SLPI到HAL层的基本链路是通的。点击Start Self Test能触发ADSP内部的sensor自测流程直接检查寄存器、通信、算法模块状态。看Offset和Calibration状态能确认sensor的校准参数是否在合理范围内。这里要特别注意一个点QsensorTest显示有数据不等于Sensor完全正常。我遇到过的情况是Accel数据在QsensorTest里刷新很正常但Framework层拿到的数据一直是0。这个时候问题就出在HAL层到Framework之间的数据转换或者sensor handle映射上跟ADSP关系不大。反过来如果QsensorTest里某个Sensor自测失败但HAL层还能读到数据那问题基本可以确定在ADSP内部的自测逻辑或者校准参数上。3.2 QsensorTest最具价值的功能事件触发验证我们平时用的很多场景比如距离感应器贴近亮屏/灭屏、抬手亮屏、计步器依赖的不是连续的数据流而是onChange事件。这种场景下QsensorTest里查看数据流曲线是看不出问题来的因为事件触发机制的验证要单独做。正确的验证姿势是在QsensorTest里选中目标Sensor比如Proximity。打开Event Monitor或事件流窗口不同版本名字略有差异。人为制造触发条件比如用手遮住Proximity、来回移动设备模拟抬手动作。观察事件触发是否及时、事件上报的次数是否正确、事件参数是否合理。我遇到过很典型的案例Proximity在遮挡时HAL层有数据变化但Framework层就是不触发灭屏。用QsensorTest做事件监测发现数据确实变了但距离值换算后的onChange事件根本没上报。顺着这个线索去抓ADSP日志定位到是SLPI里PS sensor的算法在特定距离区间内状态机卡死。这种问题直接在HAL层看数据、甚至对着代码调参是永远找不到根因的。4. 5个关键技巧把ADSP日志和QsensorTest变成定位利器前面铺垫了这么多现在把真正压箱底的东西拿出来。这5个技巧是我在多个项目里反复用、反复验证过的每个都对应一类典型的调试陷阱。4.1 技巧一抓日志前先“打标记”让无关日志自动让位ADSP日志的特点就是量大、杂、没有明显规律。如果从头到尾抓个几十秒日志文件动辄几十MB真正有用的Sensor日志混在里面查找效率极低。我的做法是在开始抓日志之前先做一个明确的触发动作然后立刻停止抓取。具体来说手动制造一个问题现象比如遮挡/移开Proximity三次或者让设备进入休眠再唤醒。在log里记录一个精确的时间戳或者记住这个动作发生的大致时间点。抓完日志后在QXDM的日志浏览器里先把时间段缩到这个动作前后几秒。在这个时间窗口内把过滤条件聚焦在SNS、APR、QMI模块不要全量看。这样做的好处是你用问题现象给日志加了一个定位锚点后续分析就不用大海捞针。如果问题本身有明确的触发动作一定不要一上来就长时间抓日志。4.2 技巧二日志级别低于阈值等于没抓——Verbose和Medium差别有多大很多人的ADSP日志抓下来Sensor模块的信息寥寥无几抱怨说“ADSP里都没打什么日志”。但真相很可能是日志级别设得太低。ADSP日志和Linux内核日志不一样它里面Sensor模块的日志是分很多级别的默认配置下只记录Error级别的内容。你得搞清楚一个现实SLPI的Sensor算法在正常运行时不打Error不打Warning它只有到了Verbose级别才把你需要的状态流转信息打出来。实际项目中我是这样配置的日志类别推荐级别原因SNS_SMGR模块VerboseSensor管理器状态机信息只在Verbose下完整输出SNS_ALGO模块Verbose算法内部判定条件、置信度计算过程需要VerboseSNS_SSI模块MediumSSI层数据流转信息Medium就够Verbose会刷屏APR/QMI模块Medium只需要看消息的发送接收和错误码其他系统模块Error降低干扰这样配置的好处是精准聚焦需要细节的模块开到Verbose只需要状态的模块开Medium无关的一律Error日志量能压缩一半以上且该有的信息一点都不少。4.3 技巧三QsensorTest测不出底层的保底手段——日志回放对比法QsensorTest连接设备后它显示的结果实际上是一份“从ADSP到HAL层”的完整链路的体检报告。但如果这份报告显示正常而你的问题依旧存在呢这时候有两种可能一是问题只在特定条件下触发比如特定温度、特定角度二是问题在Framework以上层面。我一般会用一招日志回放对比法。操作思路是这样在QsensorTest里跑一组标准测试动作记录一组“正常数据基线”。在问题复现场景下再跑同一组动作同时用QXDM抓ADSP日志。对比两次ADSP日志里Sensor输出数据的差异哪怕只是某个参数差的几个LSB往往就是问题的突破口。这个方法最讨厌的地方是需要耐心但一旦找到差异点定位就会非常精准。比如我有一次排查Gyro温漂问题对比后发现问题场景下ADSP里某个校准参数被重置成了默认值顺着这条线索往下挖最后定位到是休眠时ADSP的RAM内容丢失校准参数没有重新加载。如果不用回放对比法这种问题靠肉眼盯log真的很难发现。4.4 技巧四善用QXDM的“自定义项”窗口把HAL层和ADSP日志搬到同一时间轴Sensor调试中最痛苦的事情之一是HAL层有logADSP也有log但两边各有各的时间戳和格式很难判断哪个log对应哪个现象。我用了很久才养成一个习惯不要只盯着QDSP6 Logs窗口一定要开QSHQXDM Shell窗口执行实时命令同时留意Log窗口的时间戳。具体做法是在QXDM里同时打开QDSP6 Logs窗口、Event Log窗口和Packet Log窗口。在进行触发动作时在Event Log窗口做一个事件标记比如用Tools → Save Current Log形成一个时间点。回到办公室后把QXDM导出的日志和HAL层的log通过logcat放到同一个时间轴对比重点关注触发动作前后两个时间点。实际调试时我会把logcat抓取的sensor HAL日志里加上时间戳然后和QXDM日志的时间戳对齐。特别注意logcat和QXDM日志的设备时间一般是一致的都取系统时间所以对齐后可以精确到毫秒级。这个时间轴一旦对上了你会清晰地看到“HAL层在时间T收到了数据但ADSP在T-10ms时才上报”或者反过来的情况。谁先谁后、哪个环节卡住了一目了然。4.5 技巧五开机自动抓日志的配置——让问题自己送上门有些Sensor问题非常难复现可能跑一整天只出现一次。这种时候你不可能24小时盯在电脑前手动开关QXDM。我的方案是配置好QXDM的自动抓取功能让日志自己跑起来。在QXDM里可以这样做在Automation菜单下设置一个Trigger当某个日志条目匹配时自动开始记录。或者更简单粗暴的在连接的设备上设置好一个足够大的日志缓冲区让ADSP日志持续写入出现问题后再去抓取回放。不过我这里要提醒一句自动抓取模式下的日志量会非常大所以在自动化之前务必将过滤器设置好只保留Sensor相关的模块并把级别控制在Medium除非你已经明确知道需要Verbose级别的某个具体模块日志否则不要全开Verbose。另外有个相关的小坑有些平台的ADSP日志缓冲区在设备重启后会清空如果你要抓的是冷启动类问题比如开机时Sensor初始化失败务必在重启前就把缓冲区配置成持续保留的DDR模式否则重启瞬间日志就没了。5. 完整排查链路拿一个真实问题走一遍流程前几部分拆开了讲这部分我用一个实际排查过的典型案例把从现象到根因的完整链路串一遍。5.1 问题现象距离感应器偶尔不触发现象是手机听电话时贴近耳朵屏幕偶尔不灭或者耳朵离开了屏幕却一直黑着。不是每次都触发大概开十次会遇到一两次。用户反馈不规律重启后能恢复正常。这种问题在HAL层的log里非常难抓因为你不知道它什么时候会出现而且出现的窗口可能只有几秒钟。最开始我们尝试在HAL层连续打log观察Proximity的被遮挡状态发现偶尔接近时数据确实有变化但Framework层没有收到“near”状态。于是怀疑点指向ADSP内部。5.2 排查过程用QXDM和QsensorTest分步定位第一步先用QsensorTest做功能验证。连接设备后打开Proximity的数据流手动遮挡/移开数据正常但仔细看事件监测时发现偶尔遮挡时上报的距离值没有跌落到触发阈值以下而是停在了一个中间值。这个中间值正好让HAL层认为“不能判定为near”。第二步抓ADSP日志。拿着这个现象让同事用QXDM连上设备我手持设备遮挡/移开Proximity反复执行了大概十次。抓完日志后用前面说的标记法把时间窗缩到几次“异常遮挡”的时刻。第三步对比正常和异常的ADSP日志发现异常时刻的SNS_ALGO日志里有一个状态转换条件的数值是错的——它在遮挡时没有正确切换到near状态而是停留在了far状态。顺着这个继续查发现是Proximity芯片配置里的某个阈值寄存器被写成了默认值而不是工厂校准值。第四步回溯这个阈值为什么没有加载成功。在ADSP日志里查Sensor启动流程发现冷启动流程中SLPI从NV存储读校准参数时有一步超时超时后直接用了默认参数。问题的根因链这下彻底闭环了。5.3 踩坑复盘如果只盯一个工具会漏掉什么这个过程如果只用QsensorTest能发现事件不触发但看不到ADSP内部的状态转换问题如果只用QXDM而不配合QsensorTest做事件验证日志量太大、分析难度飙升甚至很难快速定位到异常时间段。两个工具配合起来用一个负责“快速发现问题窗口”一个负责“深挖根因细节”效率完全不一样。这也解释了为什么我在前面一直强调调试手段的组合使用比任何一种工具的“高级功能”更重要。另外提一个细节排查低概率问题时一定不要手动重复几十次去触发既浪费时间又很难保证抓到的日志覆盖问题点。我后来直接用脚本控制电机遮挡Proximity做循环触发配合QXDM自动记录日志一个晚上就能抓个几十次数据效率比手动高得多。如果你经常被这类低复现率问题折磨建议花点时间做一个简单的自动触发装置或者脚本这笔投资很值得。6. 一些容易忽略的细节和注意事项最后再补充几个零散的细节都是我在实际调试中被坑过才记住的。QXDM版本不要随便升级不同平台对工具版本有兼容性要求尤其老平台新版本QXDM可能连不上ADSP需要保留一个旧版本备用。日志文件不要起中文名说出来你可能不信我已经不止一次因为日志文件名带中文导致后续脚本分析时乱码报错耽误了大半天。ADSP日志的时区和设备时区要一致对比日志时如果时区不一致时间戳对齐的操作会让你怀疑人生。最好在抓取前确认设备时区设为UTC或北京时间并与电脑保持一致。QsensorTest的校准数据是“最后一次正常校准的数据”也就是说它显示正常不代表当前校准值有效只能代表“有校准值”。要确认校准值是否被正确加载还得回到ADSP日志里看启动时读取NV数据的打印。抓ADSP日志时尽量不要插着充电线有些设备在充电状态下电源管理策略不同会影响Sensor的休眠唤醒行为导致你抓到的问题场景和用户实际使用的场景不一致。我吃过这个亏抓了一个看似严重的问题结果拔掉充电器怎么都复现不了。这些细节单独看都不起眼但在关键时候能省下半天甚至一天的排查时间。Sensor调试本来就是个体力活能减少无效劳动就是在提升效率。