android的休眠和喚醒流程


android休眠喚醒流程:

power按鍵事件上報給android系統,最終由windownmanager接收到,當有按鍵事件時判斷是否需要休眠后喚醒系統,然后調用powermanager系統服務去寫/sys/power/state節點.
            此節點的寫函數里判斷收到的內容,來執行android的休眠early_suspend/喚醒late_resume流程.

android層:


    private int setScreenStateLocked(boolean on)                                         電源管理服務:    frameworks/base/services/java/com/android/server/PowerManagerService.java
         int err = Power.setScreenState(on);                                           
                                                                                        在文件frameworks/base/core/java/android/os/Power.java定義
                                                                                                79     public static native int setScreenState(boolean on);
                                                                                        具體實現在:frameworks/base/core/jni/android_os_Power.cpp
                                                                                                static int setScreenState(JNIEnv *env, jobject clazz, jboolean on);
                set_screen_state(on);                                                    在文件hardware/libhardware_legacy/power/power.c中定義並實現
                    write(g_fds[REQUEST_STATE], buf, len);                                寫/sys/power/state節點

                   

內核層:

向節點寫內容會調用kernel/power/main.c的寫函數:
        static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t n)
            request_suspend_state(state);                                                調用此函數:    具體實現在./kernel/power/earlysuspend.c中
                state:    為休眠則調用early_suspend_work                                    android early_suspen工作隊列
                        為喚醒則調用late_resume_work                                    android late_resume_work工作隊列
                       
                                                                                        drivers/video/samsung/s3cfb_main.c中早已經注冊屏幕開關
                                                                                            register_early_suspend(&fbdev[i]->early_suspend);
                                                                                        所以
                    為休眠則調用early_suspend_work中的屏幕休眠函數:
                            s3cfb_early_suspend()
                                backlight_on()---->s3cfb_backlight_on()                    在文件arch/arm/plat-s5p/dev-fimd-s5p.c中定義    npd->backlight_on = s3cfb_backlight_on;
                                        s3cfb_backlight_on中直接操作用來控制lcd的gpio關閉屏幕                                        arch/arm/mach-exynos/setup-fb-s5p.c
                                                   

                    為喚醒時調用late_resume_work中的屏幕喚醒函數:
                            s3cfb_late_resume()
                                backlight_off()---->s3cfb_backlight_off()                在文件arch/arm/plat-s5p/dev-fimd-s5p.c中定義    npd->backlight_off = s3cfb_backlight_off;
                                        s3cfb_backlight_off中直接操作用來控制lcd的gpio使能屏幕
               
                執行完所有的early_suspend后執行解鎖main_wake_lock,以便休眠.
                wake_unlock(&main_wake_lock);
                    mod_timer(&expire_timer, jiffies + has_lock);                        在文件/kernel/power/wakelock.c中           
                                                                                                    此函數將啟用expire_timer定時器,定時器內容即expire_wake_locks
                                                                                                    340 static DEFINE_TIMER(expire_timer, expire_wake_locks, 0, 0);

有四種方式可以引起休眠
        ①在wake_unlock()中, 如果發現解鎖以后沒有任何其他的wake lock了, 就開始休眠
        ②在定時器到時間以后, 定時器的回調函數會查看是否有其他的wake lock, 如果沒有, 就在這里讓系統進入睡眠
        ③在wake_lock() 中, 對一個wake lock加鎖以后, 會再次檢查一下有沒有鎖,             剛加上鎖,為什么要檢查,有用嗎????
        ④按power鍵,調用earlysuspend.使系統或應用程序釋放鎖.從而調用上述三個函數進入休眠
    if(has_lock ==0)
        queue_work(suspend_work_queue,&suspend_work);    由DECLARE_WORK(suspend_work, suspend);知道,隊列中的內容即suspend函數.
            suspend();                                    kernel/power/wakelock.c
                pm_suspend(requested_suspend_state);
                    enter_state(state);                    kernel/power/suspend.c
                        suspend_devices_and_enter(state);
                            suspend_enter(state);
                                suspend_ops->enter(state);            -->調用平台相關的休眠函數,定義在中arch/arm/plat-samsung/pm.c:379:static const struct platform_suspend_ops s3c_pm_ops

                          即s3c_pm_enter

            s3c_pm_arch_stop_clocks()  -->               休眠時執行的的最后一個函數.系統停在此處,等待中斷或rtc等喚醒源喚醒.

                               
                                從此處開始喚醒流程
                                enable_nonboot_cpus();
                            suspend_test_start();                    ---------->kernel已經被喚醒,當按鍵或中斷來臨后可以執行中斷函數,上報喚醒事件.對於外部中斷來說,上報power按鍵事件.
                        pm_restore_gfp_mask();            kernel/power/suspend.c
                    enter_state(state);
                 pm_suspend(suspend_state_t state);                                           
            suspend();                                    kernel/power/wakelock.c           


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM