• Linux休眠与唤醒wakelock唤醒锁与autosleep功能使用


    一、Linux系统休眠
    在嵌入式设备中由于省电功耗等原因我们需要让系统在不忙的时候进入休眠模式,Linux pm core提供给我们wakelock及autoslepp内核休眠机制。
    autosleep 和 wakelock是并行存在,只有 wakelock 唤醒锁全部释放且 autosleep 为 enable 时候系统才能进入休眠;

    二、autosleep功能
    节点路径为/sys/power/autosleep,该值为mem表示打开autoslepp功能,如果值为off表示关闭。
    如果没有此节点路径,我们需要在内核配置打开autosleep功能的宏控。
    /面朝大海0902/

    三、wakelock唤醒锁使用及查看
    Kernel wakelock 使用方法:
    Step1, 初始化
    wake_lock_init(&wake_lock, WAKE_LOCK_SUSPEND, “name”);

    Step2, 加锁
    wake_lock(&wake_lock); //与 wake_unlock 成对使用, lock 后系统不允许休眠
    wake_lock_timeout(&wake_lock, msecs_to_jiffies(timeout)); //超时锁, 超时时间到后自动释放

    Step3, 解锁
    wake_unlock(&wake_lock); //unlock 后系统允许休眠

    app wakelock 使用方法:
    Step1, 加锁
    write_lockfile("/sys/power/wake_lock", “wakelock_name”);

    Step2, 解锁
    write_lockfile("/sys/power/wake_unlock", “wakelock_name”);

    设置超时锁
    static void wake_timeout_lock(char *lockname, ULONG interval);
    /面朝大海0902/

    查看当前系统持锁情况:
    如果系统未休眠,按照上面说的内容肯定是当前系统有持锁,我们需要查看系统持锁情况,使用如下命令
    awk ‘$6 != 0 {print $1" "$6}’ /sys/kernel/debug/wakeup_sources
    该命令实际就是打印出wakeup_sources节点下active_since项为非0的锁的名称,如下

    1.~ # awk '$6 != 0 {print $1" "$6}' /sys/kernel/debug/wakeup_sources
    2.name active_since
    3.dwc_otg_pm 4442570

    表示当前USB持锁导致系统未进入休眠模式。

    ==========================================================================================================

    如何分析wakelock(wakeup source)持锁问题

    锁一般分为:APP透过PowerManager拿锁,以及kernel wakelock.

    分析上层持锁的问题:

    目前PowerManagerService的log 默认不会打开,可以通过修改:

    /frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

        private static final boolean DEBUG = true;
        private static final boolean DEBUG_SPEW = DEBUG && false;
    修改为:
        private static final boolean DEBUG = true;
        private static final boolean DEBUG_SPEW = true;
    打开上层的log

    通过syslog:搜索关键字:total_time=来确定持锁的时间.

    PowerManagerService: releaseWakeLockInternal: lock=31602562 [*job*/DownloadManager:com.android.providers.downloads], flags=0x0, total_time=600051ms

    或者通过正则表达式:total_time=[\d]{4,}ms 过滤出持锁时间比较长的锁.

    PowerManagerService: releaseWakeLockInternal: lock=31602562 [*job*/DownloadManager:com.android.providers.downloads], flags=0x0, total_time=600051ms
    PowerManagerService: releaseWakeLockInternal: lock=56317918 [*job*/DownloadManager:com.android.providers.downloads], flags=0x0, total_time=283062ms
    PowerManagerService: releaseWakeLockInternal: lock=216012597 [AudioMix], flags=0x0, total_time=120003ms
    PowerManagerService: releaseWakeLockInternal: lock=41036921 [AudioMix], flags=0x0, total_time=167984ms
    PowerManagerService: releaseWakeLockInternal: lock=70859243 [GsmInboundSmsHandler], flags=0x0, total_time=3206ms
    PowerManagerService: releaseWakeLockInternal: lock=242046348 [AudioMix], flags=0x0, total_time=122205ms

    kernel的锁默认不会打印出来,一般是待机结束后通过节点来获取:

    adb shell  cat /sys/kernel/debug/wakeup_sources >  wakeup_sources.log

    active_count:对应wakeup source被激活的次数.
    event_count:被信号唤醒的次数 
    wakeup_count:中止suspend的次数. 
    expire_count:对应wakeup source超时的次数. 
    active_since:上一次还活跃的时间点.时间单位跟kernel log前缀时间是一样(kernel单调递增时间). 
    total_time:对应wakeup source活跃的总时长. 
    max_time:对应的wakeup source持续活跃最长的一次时间. 
    last_change:上一次wakeup source变化的时间(从持锁到释放or释放到持锁),时间单位跟kernel log前缀时间是一样(kernel单调递增时间). 
    prevent_suspend_time:对应wakeup source阻止进入autosleep的总累加时间.

  • 相关阅读:
    C# 创建一个日志文件
    C# WinForm程序添加引用后调用静态方法时报“Interfaces_Helper.Global”的类型初始值设定项引发异常。---> System.NullReferenceException: 未将对象引用设置到对象的实例。
    SqlServer 一些操作
    多线程处理sql server2008出现Transaction (Process ID) was deadlocked on lock resources with another process and has been chose问题
    SQL
    WinForm 弹框确认后执行
    C#强制清除缓存
    C#TextBox自动滚动到最低端
    XmlDocument To String
    ROCK 算法
  • 原文地址:https://www.cnblogs.com/zxc2man/p/16380941.html
Copyright © 2020-2023  润新知