睡眠過程:
1.呼叫setsystempowerstate進入睡眠狀態.
2.電源管理驅動裡設定裝置的電源狀態;
3.呼叫poweroffsystem()進入核心處理;
4.呼叫各裝置驅動的powerdown();
5.呼叫oempoweroff():
(1).儲存晶元所有的暫存器值到乙個靜態陣列(就是堆疊中);
(2).先進行平台相關的動作,比如清屏,設定ad,usb等;
(3).設定io,關閉kitl等;
(4).呼叫oalcpupoweroff()進行掛起.
oalcpupoweroff()是乙個位於startup.s中的彙編函式,它按照下面的流程實現掛起功能:
a.儲存通用暫存器r4-r12,lr到堆疊;
b. 儲存wakeup後的位址,mmu暫存器,進入各模式將sp和lr暫存器儲存到記憶體ram的某乙個位置,這個位置是由config.bib指定保留的.為什麼不象之前一樣儲存到堆疊呢?因為系統喚醒後跳轉到reset開始執行,這時候堆疊還沒有初始化.這也是poweroff過程複雜的原因;
c.計算剛才儲存的資料塊的檢驗和並儲存到gstatus3暫存器.(gstatus3和gstatus4是狀態暫存器,掛起直到喚醒過程都會儲存裡面的值);
d.禁止中斷;
e.清cache;
f.使能喚醒中斷,能喚醒可以是外部中斷0,1,2,或者rtc中斷;
g.設定sdram進入自重新整理模式,最終cpu進入poweroff狀態.
喚醒過程:
cpu的poweroff模式和其他睡眠模式不同,其他的睡眠模式喚醒後會從睡眠處繼續執行,而poweroff模式喚醒後是從reset處執行.reset有3種可能情況:
(1).正常的上電冷啟動,包括reset訊號線有效造成的reset.
(2).看門狗失效造成的reset.
(3).poweroff之後被外部中斷或者rtc 中斷喚醒的reset.
在reset之後可以根據gstatus2暫存器來判斷是否從poweroff喚醒.還有乙個問題,不論何種方式reset,都是先執行bootloader的**,所以喚醒過程需要bootloader的參與配合.具體流程:
1.外部中斷或者rtc中斷喚醒cpu進入bootloader
2.bootloader中停止sdram的自重新整理模式,然後跳到核心開始位址.有些bootloader會做的更多,因為前面我們把資料都儲存到了ram中的某處,事實上只要知道這個ram位址就可以取得資料進入喚醒過程.所以有些bootloader會直接去喚醒.我認為這並不好,增加了bootloader的依賴性,層次間的耦合性也高了.
3.檢查checksum,因為之前設定sdram處於自重新整理狀態,在poweroff期間sdram裡面的資料會保持,增加checksum是有必要的安全措施.
4.從ram取得之前儲存的引數,其中包含了喚醒後應該跳轉的位址,和mmu的配置資料以及各個模式的sp和lr.
5.啟動mmu
6.跳到喚醒後的新位址.
7.進入各個模式恢復sp和lr.
8.恢復r4-r12,lr
9.跳轉到lr,即相當於oalcpupoweroff()返回,返回到oempoweroff()中.
10.開啟kitl,恢復所有暫存器,恢復平台之前狀態.
11.呼叫各裝置驅動的powerup();
12.回到電源管理驅動中,更新各裝置驅動的電源狀態;
13.電源管理驅動發出系統狀態變遷的訊息通知;
14.恢復正常。
Linux 休眠喚醒(一)
說明 1.based on linux2.6.32,only for mem sdr 2.有興趣請先參考閱讀 電源管理方案apm和acpi比較.doc linux系統的休眠與喚醒簡介.doc 4.基於手上的乙個專案來討論,這裡只討論共性的地方 雖然linux支援三種省電模式 standby susp...
Linux 休眠喚醒(一)
說明 1.based on linux2.6.32,only for mem sdr 2.有興趣請先參考閱讀 電源管理方案apm和acpi比較.doc linux系統的休眠與喚醒簡介.doc 4.基於手上的乙個專案來討論,這裡只討論共性的地方 雖然linux支援三種省電模式 standby susp...
Linux 休眠喚醒(一)
一 專案power相關的配置 目前我手上的專案的linux電源管理方案配置如下,config檔案的截圖,當然也可以通過make menuconfig使用圖形化來配置 cpu power management config cpu idle is not set power management op...