Android功耗系列专题理论之十四:Sensor功耗问题分析方法

【关注我,后续持续新增专题博文,谢谢!!!】

上一篇我们讲了:

这一篇我们开始讲: Android功耗系列专题理论之十四:Sensor功耗问题分析方法

目录

一、Sensor功耗优化方向

二、AP端唤醒优化

三、ADSP/SLPI子系统休眠问题分析

四、器件驱动问题分析与解决

五、频繁退出island问题分析思路

六、查看sensor打开情况的方法

七、异常现场抓取dump方法


一、Sensor功耗优化方向

Qcom Sensor功耗优化方向

AP端唤醒优化

检查sensor持锁唤醒AP的问题,重点关注smp2p-sleepstateqrtr持锁情况。通过分析唤醒源日志和持锁时间,定位频繁唤醒AP的sensor或服务。优化策略包括调整sensor采样率、减少不必要的数据上报,以及检查跨处理器通信机制的效率。

ADSP/SLPI子系统休眠优化

针对ADSP/SLPI子系统不休眠或休眠效率低的问题,需分析子系统电源管理策略。检查低功耗模式(如GDSP)是否正常进入,确认传感器数据处理任务的调度策略。优化方法包括调整子系统任务优先级,确保空闲时快速进入休眠,并验证传感器hub固件的低功耗配置。

器件驱动优化

硬件功耗偏高需检查传感器供电模式(如LDO配置)和时序控制。驱动配置异常需验证寄存器初始化参数是否符合低功耗场景要求。对于未放入island的驱动,需检查内存分配是否标记为CMAnocache区域,并确保关键路径代码符合低功耗岛运行条件。通过功耗测量工具(如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锁。

cpp 复制代码
kernel_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及其打开源。

cpp 复制代码
vendor/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_startd.dump __sensors_island_end确认sensor地址是否在island空间范围内(0xB20或0xB21开头地址通常为island)

常见场景及分析

  • 飞行待机场景:检查计步器、sar sensor
  • 黑屏手势场景:检查计步器、接近sensor
  • FTM模式:无sensor开启 分析方法:
  1. 确认场景下开启的sensor是否符合预期
  2. 测量各sensor开关的功耗增量,定位异常sensor
  3. 检查异常sensor是否放入island,对比《附录2:SENSOR功耗标准》或参考对比机数据
  4. 通过波形图验证功耗尖峰周期(计步器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休眠率过低时,执行以下操作:

  1. 调用分析

    • 使用dumpsys sensorservice命令输出AP层传感器调用详情。
    • 通过内核层sensor功耗埋点监控传感器列表并打印日志。
  2. 触发子系统dump

    • 调用音频或传感器脚本触发ADSP/SLPI子系统的dump,回传后分析。
  3. 问题甄别

    • 需明确休眠率低是否由传感器引起,需排除AOP(Always-On Processor)导致的子系统不休眠情况。

关键注意事项

  • 避免现场破坏:优先通过驱动或传感器触发dump,而非adb。
  • 干扰控制:选择基础传感器(如a+g)确保最小化外部影响。
  • 功耗问题定位:需结合AP层和内核层日志综合判断。

(注:以上内容基于技术文档整理,无直接外部引用。)

【关注我,后续持续新增专题博文,谢谢!!!】

下一篇讲解:

相关推荐
biter down2 小时前
C++的IO流
开发语言·c++
whycthe2 小时前
c++动态规划算法详解
c++·算法·动态规划
清 澜2 小时前
深度学习连续剧——手搓梯度下降法
c++·人工智能·面试·职场和发展·梯度
lauo2 小时前
dtnsbot分身网页版正式上线:开启“灵魂与肉身分离”的智能体远程控制新纪元
人工智能·智能手机·架构·开源·github
ByNotD0g2 小时前
Doris 学习笔记
android·笔记·学习
修炼者2 小时前
【Android进阶】 RenderEffect的底层实现
android
愚者游世2 小时前
<algorithm> 中 remove、remove_if、remove_copy、remove_copy_if 详解
c++·学习·程序人生·职场和发展·visual studio
我头发还没掉光~3 小时前
【C++写详细总结①】从for循环到算法初步
数据结构·c++·算法