攒了一些关于调试Android和Linux下面的suspend 和 resume的经验, 在这里和大家分享一下。

希望可以有些帮助, (下面没有写Android专用的, 就是Linux通用的)。

1. no_console_suspend

在kernel启动参数里面加上no_console_suspend, 这个是最基本的, 因为kernel在把console suspend掉以后, 不管里面出了什么事情, 从串口上都看不到。 大部分在suspend/resume时候的死机都可以通过串口看到kernel Panic的信息, 这样才会知道是哪里出了问题。因为有的时候resume出错, 或者suspend到很后面出错的console不加这个参数都看不到。

2. initcall_debug

这个也许知道的人不多, 其实有的时候你不知道哪个driver在suspend/resume的时候出错的时候,很迷茫, 就想在哪里加上一些调试信息来看看是哪里的driver, 其实有些时候加的不合适的话, 会看不到很多有用的信息。其实kernel本身已经有这样的功能了(只不过不是很人性化)。

echo 1 > /sys/module/kernel/parameters/initcall_debug echo 9 > /proc/sys/kernel/printk

第一条命令是打开initcall_debug, 这个是所有的kernel都会有的, 也可以在启动参数里面加initcall_debug来默认打开这个参数, 这样可以调试系统启动。

因为这些信息都是KERN_DEBUG级别的, 所以需要提高printk的级别才可以看到, 要不然suspend/resume的时候死掉了,你就没有机会看到这些信息了。

3. suspend_test

这个方法可以用rtc这种软件的方式来做循环的suspend/resume, 尽管对于Android这样并不是很足够, (你得模拟一个POWER_KEY上去才够), 但是对于调试Driver的稳定性, 还是有一定用处的。 不要以为suspend了几次可以, 那么就可以通过几千次的测试。 这个suspend是5秒钟用RTC唤醒, 然后对于Android, 5秒钟又会自动睡下去, 但是对于通用Linux, 你得写个小脚本来让他一会再睡下去, 或许这个工具比较有用rtcwakeup(google rtcwakeup)。

使用方法:

编译一个有这个功能的kernel, make menuconfig 以后选上

CONFIG_PM_DEBBUG=y

CONFIG_PM_TEST_SUSPEND=y

这两个选项

烧写新的kernel,然后打开你需要测试的东东, 比如WIFI,3G

echo "core" > /sys/power/pm_test

echo "mem" > /sys/power/state

这样, 它就会循环休眠和唤醒了。

4. wakelock

轮到Android的调试了, Android里面和Power相关最大的就是wakelock, 有时候会碰到睡不下去,或者睡到最后弹起来的问题, 就是wakelock引起的,或者说是wakelock的使用者引起的。

怎么调试呢,用一下两个:

echo 15 > /sys/module/wakelock/parameters/debug_mask

echo 15 > /sys/module/userwakelock/parameters/debug_mask

15是代表16进制的F, 在wakelock里面就是把所有的debug信息打开, 起码现在是。如果以后不够了,估计得输入255.

这样你能看到kernel和frameworks层对于wakelock的操作, 申请和释放。 这样看申请和释放成对否就可以了。注意: wakelock有一种是timeout的, 就是说多少毫秒以后, 会自动释放, 对于这些wakelock, 申请和释放可能是不成对的。。

5. power.0

有的时候你会看到系统suspend到了最后, 然后遇到power.0 suspend失败,然后整个系统都又resume起来了。 这个是android专有的,因为power.0是android注册到suspend最后的一个回调, 它会在CPU进入suspend之前检查一下有没有wakelock, 如果这时候还有没有释放的wakelock, 那么它会返回-EBUSY然后导致整个suspend失败。 调试这个问题的方法就是把上面wakelock的debug信息打开, 然后看看是哪个家伙去申请了wakelock,然后干掉它。

这个错误的错误信息大概是这样的:

pm_noirq_op(): platform_pm_suspend_noirq+0x0/0x38 returns -11
PM: Device power.0 failed to suspend late: error -11

6. earlysuspend

差点忘掉这个哥们, android里面另外一个pm相关的大东东, 同样可以加:

echo 15 > /sys/module/earlysuspend/parameters/debug_mask

来把相关的debug信息打印出来, 比如那个earlysuspend要被call之类的。

7. suspend/resume time.

有的时候你要调试suspend/resume的时间太慢的问题。 一种方法是用initcall_debug, 然后把printk的时间戳打上, 然后看哪个很慢。

但是这样会让你的生活很枯燥:)

我有一个patch,专门用来调试这个问题的,但是upstream不接受, 说非要用这种折磨人的方法才行, 但是如果你想用可以下下来打上去用一下。

地址在这里:http://www.spinics.net/lists/linux-pm/msg24063.html

用法是, 打上这个PATCH以后, 在KERNEL里面选择上PM_DEBUG, SUSPEND_DEVICE_TIME_DEBUG 这两个选项。

然后

echo 微秒 > /sys/power/device_suspend_time_threshold

比如

echo 50000 > /sys/power/device_suspend_time_threshold

注意这里是微秒哦。。。 它会把在suspend/resume的时候慢的那些driver打出来,然后你去干掉它。。。

更多相关文章

  1. android 中使用java aes加密算法,报错信息android javax.crypto.B
  2. Android从SD卡中加载图片或读取信息
  3. android segment fault logcat相关信息分析
  4. android alarm相关信息
  5. Android中图形参数及图形内存信息获取
  6. android中异步加载图片信息
  7. Android 读取SIM卡参数
  8. 查看Android apk签名信息
  9. Android检测版本更新(读取apk配置文件中的版本信息)

随机推荐

  1. 收紧 Android(安卓)控制权,Google 或强制
  2. Android新手入门 FAQ
  3. Android视频采集
  4. 手把手的教你成为Android高手(视频+源码+
  5. Android(安卓)UI开发(一)初识安卓
  6. c++11 + SDL2 + ffmpeg +OpenAL + java =
  7. Android高手进阶教程(四)之----Android(
  8. Android(安卓)高工面试必考题(二):Android的
  9. Android中的消息机制
  10. 解析底层原理!月薪20k+的Android面试都问