【关注我,后续持续新增专题博文,谢谢!!!】
上一篇我们讲了:
这一篇我们开始讲: Android功耗系列专题理论之十四:Sensor功耗问题分析方法
目录
一、Sensor功耗优化方向
Qcom Sensor功耗优化方向
AP端唤醒优化
检查sensor持锁唤醒AP的问题,重点关注
smp2p-sleepstate和qrtr持锁情况。通过分析唤醒源日志和持锁时间,定位频繁唤醒AP的sensor或服务。优化策略包括调整sensor采样率、减少不必要的数据上报,以及检查跨处理器通信机制的效率。ADSP/SLPI子系统休眠优化
针对ADSP/SLPI子系统不休眠或休眠效率低的问题,需分析子系统电源管理策略。检查低功耗模式(如
GDSP)是否正常进入,确认传感器数据处理任务的调度策略。优化方法包括调整子系统任务优先级,确保空闲时快速进入休眠,并验证传感器hub固件的低功耗配置。器件驱动优化
硬件功耗偏高需检查传感器供电模式(如LDO配置)和时序控制。驱动配置异常需验证寄存器初始化参数是否符合低功耗场景要求。对于未放入island的驱动,需检查内存分配是否标记为
CMA或nocache区域,并确保关键路径代码符合低功耗岛运行条件。通过功耗测量工具(如PowerTOP)定位异常耗电模块。问题排查工具建议
- 使用
sysfs接口查看传感器状态:/sys/class/sensors- 分析唤醒源:
cat /sys/kernel/wakeup_sources- ADSP/SLPI日志工具:高通
ADSPRPC调试工具或sysmon日志- 功耗测量:
Battery Historian结合powermonitor硬件工具代码检查示例
验证驱动是否标记为island兼容:
static struct platform_driver sensor_driver = { .driver = { .name = "sensor-dev", .pm = &sensor_pm_ops, .of_match_table = sensor_match_table, .probe_type = PROBE_FORCE_SYNCHRONOUS, }, .probe = sensor_probe, .remove = sensor_remove, };需确认
pm_ops包含runtime_suspend/resume回调,且DTS配置中电源域标记为qcom,island-mode。
二、AP端唤醒优化
ap唤醒分析流程
smp2p-sleepstate持锁
sensor作为wakeup sensor,client端为AP。为避免事件丢失,wakeup sensor发送数据后会调用smp2p_write唤醒AP,AP唤醒后将持有200ms锁。
cppkernel_platform/msm-kernel/drivers/soc/qcom/smp2p_sleepstate.c 50 static irqreturn_t smp2p_sleepstate_handler(int irq, void *ctxt) 51 { 52 __pm_wakeup_event(notify_ws, 200); 53 return IRQ_HANDLED; 54 } 56 static int smp2p_sleepstate_probe(struct platform_device *pdev) 57 { 58 int ret; 59 int irq; 60 struct device *dev = &pdev->dev; 61 struct device_node *node = dev->of_node; 62 63 state = qcom_smem_state_get(&pdev->dev, 0, &ret); 64 if (IS_ERR(state)) 65 return PTR_ERR(state); 66 qcom_smem_state_update_bits(state, AWAKE_BIT, AWAKE_BIT); 67 68 ret = register_pm_notifier(&sleepstate_pm_nb); 69 if (ret) { 70 dev_err(dev, "%s: power state notif error %d\n", __func__, ret); 71 return ret; 72 } 73 74 notify_ws = wakeup_source_register(&pdev->dev, "smp2p-sleepstate"); 75 if (!notify_ws) { 76 return -ENOMEM; 77 goto err_ws; 78 } 79 80 irq = of_irq_get_byname(node, "smp2p-sleepstate-in"); 81 if (irq <= 0) { 82 dev_err(dev, "failed to get irq for smp2p_sleep_state\n"); 83 ret = -EPROBE_DEFER; 84 goto err; 85 } 86 dev_dbg(dev, "got smp2p-sleepstate-in irq %d\n", irq); 87 // CR#3918899 88 ret = devm_request_threaded_irq(dev, irq, NULL, 89 smp2p_sleepstate_handler, 90 IRQF_ONESHOT | IRQF_TRIGGER_RISING | 91 IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND, 92 "smp2p_sleepstate", dev); 93 if (ret) { 94 dev_err(dev, "fail to register smp2p threaded_irq=%d\n", irq); 95 goto err; 96 } 97 return 0; 98 err: 99 wakeup_source_unregister(notify_ws); 100 __pm_relax(notify_ws); 101 err_ws: 102 unregister_pm_notifier(&sleepstate_pm_nb); 103 return ret; 104 }hal层需检查wake up sensor打印,新平台需移植该打印功能以便调试。匹配smp2p唤醒打印与hal层wake up sensor打印,确认上报数据是否为预期行为。异常情况下频繁唤醒AP需排查sensor配置,不匹配时需检查其他可能唤醒AP的sensor及其打开源。
cppvendor/qcom/proprietary/sensors-see/sensors-hal-2.0/framework/ssc_sensor.cpp 599 void ssc_sensor::ssc_conn_event_cb(const uint8_t *data, size_t size, uint64_t sample_received_ts) 600 { 601 SNS_TRACE_BEGIN("sensors::ssc_conn_event_cb"); 602 632 if(SENSOR_WAKEUP == _wakeup_type) { 633 sns_logi("event[%d] msg_id=%d, ts=%llu sensor_type = %s", sample_count, pb_event.msg_id(), 634 (unsigned long long) pb_event.timestamp(), _sensor_name.c_str()); 635 } else { 636 sns_logv("event[%d] msg_id=%d, ts=%llu sensor_type = %s", sample_count, pb_event.msg_id(), 637 (unsigned long long) pb_event.timestamp(), _sensor_name.c_str()); 638 }qrtr持锁
QRTR(Qualcomm IPC Router)唤醒打印信息提供了关于通信源、目标和服务的关键信息。qrtr协议用于处理器间无线通信,日志通过ipc_logging接口保存至预分配的ipc buffer。子系统传输数据时可获取qrtr_ws锁唤醒AP以确保传输成功。
qrtr唤醒日志格式示例:
qrtr_print_wakeup_reason: src[0x5:0xe] dst[0x1:0x4024] [12160006 0035017e] service[0x1001]。其中node id 0x5对应子系统,service 0x1001表示Diag service。
三、ADSP/SLPI子系统休眠问题分析
ADSP/SLPI子系统休眠问题分析
休眠比统计方法
通过共享内存获取子系统中收集的休眠时间数据。统计的起始时间为进入island模式的时间点,结束时间为退出island模式的时间点。
影响休眠比的关键因素
休眠比主要受wakeup rate和island模式行为影响:
- wakeup rate超过400Hz时,子系统无法进入休眠状态。例如开启direct_channel(固定wakeup rate为500Hz)时触发此限制。
- 频繁退出island模式会显著降低休眠比。
问题分析流程
数据采集准备
功耗模块确认sensor导致休眠问题后,需捕获异常场景下的dump文件进行解析,或通过内核功耗埋点日志辅助分析。
island空间状态检查
检查instance的island_operation标志是否为SNS_ISLAND_STATE_IN_ISLAND,确认sensor是否运行在island空间。
island模式持续时间分析
确认当前是否处于island模式,并提取最近一次island模式的持续时间数据。
wake-up rate与延迟检测
- normal_mode_wakeup_rate超过50Hz时,ADSP无法进入island模式
- island_mode_wakeup_rate超过400Hz时,ADSP无法维持island模式
- 执行ssc_pwr_sleep_mgr.cmm脚本解析具体sensor的wake-up rate投票情况。各sensor的投票率会累加,通过suid可追溯对应sensor。延迟值latency_us≤500μs(非零)通常会导致ADSP保持活跃状态。
MCPS负载监控
当MCPS(Million Cycles Per Second)达到800时,ADSP会进入高性能模式,此时功耗会明显上升。
island退出原因追踪
通过解析dump文件中的F3日志,重点检查island exit相关记录,分析退出频率及具体触发原因。典型原因包括中断风暴、高优先级任务抢占等。
四、器件驱动问题分析与解决
硬件功耗偏高 通过测试特定场景下打开sensor的电流增量,与其他项目对比确认是否偏高。确认后联系硬件或厂家确认能否优化硬件配置,若无法优化需联合硬件团队澄清说明。
驱动配置异常 使用《附录1:sensor功耗测试方法》定位异常sensor后,重点检查以下方向:是否配置为island模式、是否因数据上报唤醒AP、中断或timer频率是否过高。
驱动未放入island QCOM的island模式可将sensor运行在SRAM以降低功耗。灭屏常开sensor(如acc、alsps、pickup)需放入island,亮屏常开sensor(如msensor)通常不放入。核查步骤:
- 检查驱动build文件中的相关宏配置
- 在
por.py中添加对应宏- 触发dump后通过T32工具检查,加载
ssc\tools\cmm_scripts\ssc_parser.cmm脚本- 使用指令
d.dump __sensors_island_start和d.dump __sensors_island_end确认sensor地址是否在island空间范围内(0xB20或0xB21开头地址通常为island)常见场景及分析
- 飞行待机场景:检查计步器、sar sensor
- 黑屏手势场景:检查计步器、接近sensor
- FTM模式:无sensor开启 分析方法:
- 确认场景下开启的sensor是否符合预期
- 测量各sensor开关的功耗增量,定位异常sensor
- 检查异常sensor是否放入island,对比《附录2:SENSOR功耗标准》或参考对比机数据
- 通过波形图验证功耗尖峰周期(计步器0.5s,sar sensor0.2s,接近sensor与wait time一致)
关键指令与检查点
- 地址检查:
v.v (sns_fw_sensor*)0xB2035150- 函数检查:确认关键函数是否标记为island属性
- 功耗标准:参考《附录2》中各类sensor的基准功耗值
五、频繁退出island问题分析思路
频繁退出island问题分析思路
针对island频繁退出的问题,主要通过抓取dump进行分析。触发dump后,重点观察island的退出调用栈,以定位问题根源。
屏显相关功能场景分析
在涉及屏显功能(如息屏显示)的场景下,若出现sensor频繁退出island的问题,需优先确认是否与无法使用LLC(Low Latency Client)相关。LLC的可用性直接影响island的稳定性。
排查步骤
检查系统日志中与island退出相关的错误信息,重点关注时间戳和上下文。
分析dump文件中的调用栈,识别退出的触发点,如特定函数或异常条件。
验证LLC配置和状态,确保其正常运行。若LLC不可用,需进一步排查其失效原因。
解决方案
优化LLC的资源配置和调度策略,确保其在高负载场景下的稳定性。
调整屏显功能的sensor调用逻辑,避免频繁唤醒或退出island。
在代码层面增加异常处理机制,防止因临时错误导致island意外退出。
六、查看sensor打开情况的方法
查看sensor打开情况的方法
AP端通过sensorservice打开sensor
使用
adb shell "dumpsys sensorservice"指令查看sensor状态。log文件路径为common\SI_stop\dumpsys_sensorservice.txt,该文件记录了sensorservice对sensor的打开状态及开关历史。
- 状态标识:
+表示active,-表示deactive。- 第三方应用:在
Previous Registrations:中显示为+,但因其代理机制可忽略;需重点关注系统应用是否异常监听。NCS直接打开sensor
当前仅能通过NCS确认sensor是否被直接打开,无其他dump或日志工具支持。
Modem打开sensor
需直接联系Modem团队确认sensor打开状态,无自动化dump方法。
解析dump文件确认sensor打开情况
抓取异常现场的dump文件进行分析:
- 检查是否存在wakeup类型且请求源为AP的sensor。
- 关键判断依据:若存在
instance字段,表明该sensor已被打开。需结合场景判断其合理性。通过kernel功耗埋点监控sensor
适用于版本14.0.1及以上:
- 功能:监控指定sensor的打开状态及AP/Modem的请求记录。
- 触发条件:当DCS检测到sensor子系统休眠比过低时,自动调用接口打印数据至kernel log。
- 输出内容:包括sensor开关状态及经过CM的所有请求日志。
七、异常现场抓取dump方法
异常现场抓取dump方法
本地稳定复现类问题:编译特殊版本触发dump
通过摇晃手机触发dump,利用加速度计(acc)数据超过设定阈值实现。该方法避免连接adb唤醒AP(应用处理器),从而保护异常现场完整性。
触发原理:
- 加速度计和陀螺仪(a+g)是基础传感器,多数场景下默认开启(如FTM模式下modem注册motion_recognition,或计步器常开状态)。
- 通过a+g触发不会引入额外干扰因素。
试用反馈类问题:功耗模块检测休眠比低触发dump
当检测到ADSP休眠率过低时,执行以下操作:
调用分析
- 使用
dumpsys sensorservice命令输出AP层传感器调用详情。- 通过内核层
sensor功耗埋点监控传感器列表并打印日志。触发子系统dump
- 调用音频或传感器脚本触发ADSP/SLPI子系统的dump,回传后分析。
问题甄别
- 需明确休眠率低是否由传感器引起,需排除AOP(Always-On Processor)导致的子系统不休眠情况。
关键注意事项
- 避免现场破坏:优先通过驱动或传感器触发dump,而非adb。
- 干扰控制:选择基础传感器(如a+g)确保最小化外部影响。
- 功耗问题定位:需结合AP层和内核层日志综合判断。
(注:以上内容基于技术文档整理,无直接外部引用。)
【关注我,后续持续新增专题博文,谢谢!!!】
下一篇讲解: