日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux中_countof函数,Linux电源管理(8)_Wakeup count功能

發(fā)布時間:2023/12/20 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux中_countof函数,Linux电源管理(8)_Wakeup count功能 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Linux電源管理(8)_Wakeup count功能

作者:wowo 發(fā)布于:2014-9-12 23:35

分類:電源管理子系統(tǒng)

1. 前言

Wakeup count是Wakeup events framework的組成部分,用于解決“system suspend和system wakeup events之間的同步問題”。本文將結(jié)合“Linux電源管理(6)_Generic PM之Suspend功能”和“Linux電源管理(7)_Wakeup events framework”兩篇文章,分析wakeup count的功能、實現(xiàn)邏輯、背后的思考,同時也是對這兩篇文章的復(fù)習(xí)和總結(jié)。

2. wakeup count在電源管理中的位置

wakeup count的實現(xiàn)位于wakeup events framework中(drivers/base/power/wakeup.c),主要為兩個模塊提供接口:通過PM core向用戶空間提供sysfs接口;直接向autosleep(請參考下一篇文章)提供接口。

3. wakeup count的功能

wakeup count的功能是suspend同步,實現(xiàn)思路是這樣的:

1)任何想發(fā)起電源狀態(tài)切換的實體(可以是用戶空間電源管理進(jìn)程,也可以是內(nèi)核線程,簡稱C),在發(fā)起狀態(tài)切換前,讀取系統(tǒng)的wakeup counts(該值記錄了當(dāng)前的wakeup event總數(shù)),并將讀取的counts告知wakeup events framework。

2)wakeup events framework記錄該counts到一個全局變量中(saved_count)。

3)隨后C發(fā)起電源狀態(tài)切換(如STR),執(zhí)行suspend過程。

4)在suspend的過程中,wakeup events framework照舊工作(直到系統(tǒng)中斷被關(guān)閉),上報wakeup events,增加wakeup events counts。

5)suspend執(zhí)行的一些時間點(可參考“Linux電源管理(6)_Generic PM之Suspend功能”),會調(diào)用wakeup? events framework提供的接口(pm_wakeup_pending),檢查是否有wakeup沒有處理。

6)檢查邏輯很簡單,就是比較當(dāng)前的wakeup counts和saved wakeup counts(C發(fā)起電源狀態(tài)切換時的counts),如果不同,就要終止suspend過程。

4. wakeup count的實現(xiàn)邏輯

4.1 一個例子

在進(jìn)行代碼分析之前,我們先用偽代碼的形式,寫出一個利用wakeup count進(jìn)行suspend操作的例子,然后基于該例子,分析相關(guān)的實現(xiàn)。

1: do {

2: ret = read(&cnt, "/sys/power/wakeup_count");

3: if (ret) {

4: ret = write(cnt, "/sys/power/wakeup_count");

5: } else {

6: countine;

7: }

8: } while (!ret);

9:

10: write("mem", "/sys/power/state");

11:

12: /* goto here after wakeup */

例子很簡單:

a)讀取wakeup count值,如果成功,將讀取的值回寫。否則說明有正在處理的wakeup events,continue。

b)回寫后,判斷返回值是否成功,如果不成功(說明讀、寫的過程中產(chǎn)生了wakeup events),繼續(xù)讀、寫,直到成功。成功后,可以觸發(fā)電源狀態(tài)切換。

4.2 /sys/power/wakeup_count

wakeup_count文件是在kernel/power/main.c中,利用power_attr注冊的,如下(大家可以仔細(xì)研讀一下那一大段注釋,內(nèi)核很多注釋寫的非常好,而好的注釋,就是軟件功力的體現(xiàn)):

1: /*

2: * The 'wakeup_count' attribute, along with the functions defined in

3: * drivers/base/power/wakeup.c, provides a means by which wakeup events can be

4: * handled in a non-racy way.

5: *

6: * If a wakeup event occurs when the system is in a sleep state, it simply is

7: * woken up. In turn, if an event that would wake the system up from a sleep

8: * state occurs when it is undergoing a transition to that sleep state, the

9: * transition should be aborted. Moreover, if such an event occurs when the

10: * system is in the working state, an attempt to start a transition to the

11: * given sleep state should fail during certain period after the detection of

12: * the event. Using the 'state' attribute alone is not sufficient to satisfy

13: * these requirements, because a wakeup event may occur exactly when 'state'

14: * is being written to and may be delivered to user space right before it is

15: * frozen, so the event will remain only partially processed until the system is

16: * woken up by another event. In particular, it won't cause the transition to

17: * a sleep state to be aborted.

18: *

19: * This difficulty may be overcome if user space uses 'wakeup_count' before

20: * writing to 'state'. It first should read from 'wakeup_count' and store

21: * the read value. Then, after carrying out its own preparations for the system

22: * transition to a sleep state, it should write the stored value to

23: * 'wakeup_count'. If that fails, at least one wakeup event has occurred since

24: * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it

25: * is allowed to write to 'state', but the transition will be aborted if there

26: * are any wakeup events detected after 'wakeup_count' was written to.

27: */

28:

29: static ssize_t wakeup_count_show(struct kobject *kobj,

30: struct kobj_attribute *attr,

31: char *buf)

32: {

33: unsigned int val;

34:

35: return pm_get_wakeup_count(&val, true) ?

36: sprintf(buf, "%u\n", val) : -EINTR;

37: }

38:

39: static ssize_t wakeup_count_store(struct kobject *kobj,

40: struct kobj_attribute *attr,

41: const char *buf, size_t n)

42: {

43: unsigned int val;

44: int error;

45:

46: error = pm_autosleep_lock();

47: if (error)

48: return error;

49:

50: if (pm_autosleep_state() > PM_SUSPEND_ON) {

51: error = -EBUSY;

52: goto out;

53: }

54:

55: error = -EINVAL;

56: if (sscanf(buf, "%u", &val) == 1) {

57: if (pm_save_wakeup_count(val))

58: error = n;

59: }

60:

61: out:

62: pm_autosleep_unlock();

63: return error;

64: }

65:

66: tr(wakeup_count);

實現(xiàn)很簡單:read時,直接調(diào)用pm_get_wakeup_count(注意第2個參數(shù));write時,直接調(diào)用pm_save_wakeup_count(注意用戶空間的wakeup count功能和auto sleep互斥,會在下篇文章解釋原因)。這兩個接口均是wakeup events framework提供的接口,跟著代碼往下看吧。

4.3 pm_get_wakeup_count

pm_get_wakeup_count的實現(xiàn)如下:

1: bool pm_get_wakeup_count(unsigned int *count, bool block)

2: {

3: unsigned int cnt, inpr;

4:

5: if (block) {

6: DEFINE_WAIT(wait);

7:

8: for (;;) {

9: prepare_to_wait(&wakeup_count_wait_queue, &wait,

10: TASK_INTERRUPTIBLE);

11: split_counters(&cnt, &inpr);

12: if (inpr == 0 || signal_pending(current))

13: break;

14:

15: schedule();

16: }

17: finish_wait(&wakeup_count_wait_queue, &wait);

18: }

19:

20: split_counters(&cnt, &inpr);

21: *count = cnt;

22: return !inpr;

23: }

該接口有兩個參數(shù),一個是保存返回的count值得指針,另一個指示是否block,具體請參考代碼邏輯:

a)如果block為false,直接讀取registered wakeup events和wakeup events in progress兩個counter值,將registered wakeup events交給第一個參數(shù),并返回wakeup events in progress的狀態(tài)(若返回false,說明當(dāng)前有wakeup events正在處理,不適合suspend)。

b)如果block為true,定義一個等待隊列,等待wakeup events in progress為0,再返回counter。

注1:由4.2小節(jié)可知,sysfs發(fā)起的read動作,block為true,所以如果有正在處理的wakeup events,read進(jìn)程會阻塞。其它模塊(如auto sleep)發(fā)起的read,則可能不需要阻塞。

4.4 pm_save_wakeup_count

pm_save_wakeup_count的實現(xiàn)如下:

1: bool pm_save_wakeup_count(unsigned int count)

2: {

3: unsigned int cnt, inpr;

4: unsigned long flags;

5:

6: events_check_enabled = false;

7: spin_lock_irqsave(&events_lock, flags);

8: split_counters(&cnt, &inpr);

9: if (cnt == count && inpr == 0) {

10: saved_count = count;

11: events_check_enabled = true;

12: }

13: spin_unlock_irqrestore(&events_lock, flags);

14: return events_check_enabled;

15: }

1)注意這個變量,events_check_enabled,如果它不為真,pm_wakeup_pending接口直接返回false,意味著如果不利用wakeup count功能,suspend過程中不會做任何wakeup events檢查,也就不會進(jìn)行任何的同步。

2)解除當(dāng)前的registered wakeup events、wakeup events in progress,保存在變量cnt和inpr中。

3)如果寫入的值和cnt不同(說明讀、寫的過程中產(chǎn)生events),或者inpr不為零(說明有events正在被處理),返回false(說明此時不宜suspend)。

4)否則,events_check_enabled置位(后續(xù)的pm_wakeup_pending才會干活),返回true(可以suspend),并將當(dāng)前的wakeup count保存在saved count變量中。

4.5 /sys/power/state

再回憶一下“Linux電源管理(6)_Generic PM之Suspend功能”中suspend的流程,在suspend_enter接口中,suspend前的最后一刻,會調(diào)用pm_wakeup_pending接口,代碼如下:

1: static int suspend_enter(suspend_state_t state, bool *wakeup)

2: {

3: ...

4: error = syscore_suspend();

5: if (!error) {

6: *wakeup = pm_wakeup_pending();

7: if (!(suspend_test(TEST_CORE) || *wakeup)) {

8: error = suspend_ops->enter(state);

9: events_check_enabled = false;

10: }

11: syscore_resume();

12: }

13: ...

14: }

在write wakeup_count到調(diào)用pm_wakeup_pending這一段時間內(nèi),wakeup events framework會照常產(chǎn)生wakeup events,因此如果pending返回true,則不能“enter”,終止suspend吧!

注2:wakeup后,會清除events_check_enabled標(biāo)記。

“Linux電源管理(7)_Wakeup events framework”中已經(jīng)介紹過pm_wakeup_pending了,讓我們再看一遍吧:

1: bool pm_wakeup_pending(void)

2: {

3: unsigned long flags;

4: bool ret = false;

5:

6: spin_lock_irqsave(&events_lock, flags);

7: if (events_check_enabled) {

8: unsigned int cnt, inpr;

9:

10: split_counters(&cnt, &inpr);

11: ret = (cnt != saved_count || inpr > 0);

12: events_check_enabled = !ret;

13: }

14: spin_unlock_irqrestore(&events_lock, flags);

15:

16: if (ret)

17: print_active_wakeup_sources();

18:

19: return ret;

20: }

a)首先會判斷events_check_enabled是否有效,無效直接返回false。有效的話:

b)獲得cnt和inpr,如果cnt不等于saved_count(說明這段時間內(nèi)有events產(chǎn)生),或者inpr不為0(說明有events正在被處理),返回true(告訴調(diào)用者,放棄吧,時機(jī)不到)。同時清除events_check_enabled的狀態(tài)。

c)否則,返回false(放心睡吧),同時保持events_check_enabled的置位狀態(tài)(以免pm_wakeup_pending再次調(diào)用)。

Okay,結(jié)束了,等待wakeup吧~~~~

原創(chuàng)文章,轉(zhuǎn)發(fā)請注明出處。蝸窩科技,www.wowotech.net。

評論:

catamout

2020-03-12 10:45

bool pm_wakeup_pending(void)

首先會判斷events_check_enabled是否有效,無效直接返回false。

在kernel/power/suspend_test.c中test_suspend進(jìn)入休眠的流程events_check_enabled == false,那休眠的整個過程中,pm_wakeup_pending的返回值都是false,沒有去檢測是否有event產(chǎn)生。

是否存在其他events_check_enabled == false時,系統(tǒng)進(jìn)入休眠的情況?

cym

2017-11-01 11:07

Hi wowo

在N上遇到有很多的wakeup source:

Line 571: 09-16 09:44:07.490???? 0???? 0 I???????? : [460489.904631,1] last active wakeup source: ipc000002b2_PowerManagerSer

Line 657: 09-16 09:44:09.380???? 0???? 0 I???????? : [460491.346436,0] last active wakeup source: ipc000002b2_PowerManagerSer

Line 717: 09-16 09:44:11.446???? 0???? 0 I???????? : [460492.174366,2] last active wakeup source: ipc000002b2_PowerManagerSer

Line 895: 09-16 09:44:17.257???? 0???? 0 I???????? : [460494.912370,1] last active wakeup source: ipc000002b2_PowerManagerSer

Line 987: 09-16 09:44:18.967???? 0???? 0 I???????? : [460496.271585,2] last active wakeup source: ipc000002b2_PowerManagerSer

Line 1106: 09-16 09:44:24.730???? 0???? 0 I???????? : [460501.129454,2] last active wakeup source: ipc000002b2_PowerManagerSer

請問下你知道這是怎么產(chǎn)生的嗎??

Rafe

2017-09-12 16:06

@wowo

請教一個問題:

我在高通的power key driver中看到,當(dāng)設(shè)備處于suspend mode的時候,按power key喚醒設(shè)備,中斷處理僅僅通過input子系統(tǒng)上報鍵值。且上報前沒有任何的延遲操作。

所以我覺得這個時候,用戶空間進(jìn)程應(yīng)該會存在還未resume回來或者沒有被調(diào)度到的情況,而autosleep timeout,緊接著再次進(jìn)入suspend mode。

而我現(xiàn)在看到的現(xiàn)象是從沒出現(xiàn)過這種情況,我現(xiàn)在就是不清楚是像我猜測的那樣?

還是每次用戶空間都能準(zhǔn)時收到?又或者Linux的電源管理部分有相關(guān)的地方保證了消息的發(fā)送處理?

2017-09-13 16:39

@Rafe:你這個問題很有意思,確實像你說的那樣,有些powerkey的上報根本沒有處理wakeup event有關(guān)的內(nèi)容,之所以沒有出問題,我的猜測是(只是猜測,沒有仔細(xì)分析,有空的話你可以試試):

1)用戶空間程序(例如android的EventHub,frameworks/native/services/inputflinger/EventHub.cpp)一直都poll(等待)在key event上。

2)當(dāng)power key事件上報的時候,kernel會wakeup等待隊列,以便讓用戶空間程序執(zhí)行并讀取到鍵值。

3)在等待的線程被執(zhí)行之前,系統(tǒng)不能(或者沒有機(jī)會)再次被休眠(autosleep也是在線程中?),直到等待的線程醒來。

4)處理鍵值的線程醒來執(zhí)行后,就好辦了~~~

mallocnew

2017-03-21 23:16

非常感謝就是還有個小疑問:

pm_save_wakeup_count中的

3)如果寫入的值和cnt不同(說明讀、寫的過程中產(chǎn)生events),或者inpr不為零(說明有events正在被處理),返回false(說明此時不宜suspend)。

以及pm_wakeup_pending中的

b)獲得cnt和inpr,如果cnt不等于saved_count(說明這段時間內(nèi)有events產(chǎn)生),或者inpr不為0(說明有events正在被處理),返回true(告訴調(diào)用者,放棄吧,時機(jī)不到)。同時清除events_check_enabled的狀態(tài)。

inpr不為0,停止suspend能理解,而對于“寫入的值和cnt不同”和“cnt不等于saved_count”,cnt不是記錄的已經(jīng)處理完成的event的個數(shù)嗎?如果event已經(jīng)處理完成了,為什么要停止suspend而不是繼續(xù)suspend呢?

2017-03-22 08:47

@mallocnew:文中的表述是:

“讀取系統(tǒng)的wakeup counts(該值記錄了當(dāng)前的wakeup event總數(shù))”

所以這是總數(shù),不是已處理數(shù)。

jiangxinyu

2016-11-16 11:44

@wowo:

你好,有個問題請教下,我想建立一個驅(qū)動,里面實現(xiàn)suspend/resume接口,目的是在系統(tǒng)休眠和喚醒時分別被調(diào)用,用來實現(xiàn)一些功能控制外設(shè)的功能, 目前已經(jīng)成功注冊到Linux pm模塊。當(dāng)我手動執(zhí)行echo mem > sys/power/state的時候,我寫的suspend/resume能夠成功執(zhí)行。但是,現(xiàn)在的問題是,當(dāng)我的Android設(shè)備自動進(jìn)入休眠或者手按power鍵的時候,我的suspend/resume函數(shù)沒有被調(diào)用,我追了一下,發(fā)現(xiàn)系統(tǒng)休眠的時候,貌似并沒有執(zhí)行sys/power/state這個節(jié)點,難道Android系統(tǒng)進(jìn)入休眠的時候不走Linux的PM機(jī)制?

期待您的答復(fù)!

2016-11-16 13:05

@jiangxinyu:舊版本的android,很多確實沒有使用kernel標(biāo)準(zhǔn)的電源管理框架,轉(zhuǎn)而使用自定義的early suspend機(jī)制,你可以檢查一下你的代碼。

jiangxinyu

2016-11-16 14:28

@wowo:@wowo:

您好,我的suspend/resume能夠被調(diào)用到了,原因是連著USB抓的實時log,汗。。

還有兩個個問題:

1 APP獲取的wake_lock最終會走到sys/power/wake_lock嗎?也就是說APP申請的鎖是不是最終也會進(jìn)入kernel空間?

2 假如后臺有應(yīng)用一直在跑(一直占用wake_lock),sys/power/state永遠(yuǎn)不會被寫入mem,是這樣嗎?

2016-11-16 21:25

@jiangxinyu:如果android使用linux kernel標(biāo)準(zhǔn)的autosleep、wakelock機(jī)制,你提到的這兩點是對的。

2020-10-13 10:57

@jiangxinyu:是的,android某些版本,播放音樂時 即使按下power-key黑屏,系統(tǒng)也不會suspend,原因就是music app一直take wake_lock。

2016-10-20 18:36

cracker

12 分鐘前

@wowo:在_device_suspend如下代碼

if (pm_runtime_barrier(dev) && device_may_wakeup(dev))

pm_wakeup_event(dev, 0);(1)

if (pm_wakeup_pending()) {?????? (2)

pm_get_active_wakeup_sources(suspend_abort,

MAX_SUSPEND_ABORT_LEN);

log_suspend_abort_reason(suspend_abort);

async_error = -EBUSY;

goto Complete;

}

這段代碼(2)處不是在做設(shè)備睡眠前的最后檢查嗎?因為這里檢查完就調(diào)用dirver->pm->suspend去關(guān)中斷了。如果設(shè)備沒有wakeup event,才會走到syscore_suspend

另外,(1)處的作用是什么呢?

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

并不是所有設(shè)備都希望關(guān)中斷,特別是那些有喚醒能力的設(shè)備。另外沒有規(guī)定dirver->pm->suspend一定會關(guān)中斷。

(1)處的作用,正好是處理那些有喚醒能力的設(shè)備,怎么處理呢?參考代碼的注釋就行了(確保此時這個設(shè)備能醒來,以便為當(dāng)前的事情做準(zhǔn)備):

/*

* If a device configured to wake up the system from sleep states

* has been suspended at run time and there's a resume request pending

* for it, this is equivalent to the device signaling wakeup, so the

* system suspend operation should be aborted.

*/

2016-10-20 19:05

@wowo:1、是不是可以這么理解:suspend_ops->enter(state)這里是保持suspend最后的狀態(tài),如果有中斷信號(這個狀態(tài)已經(jīng)不依賴wakeup count終止suspend),然后syscore_resume()?

2、我有最簡單的疑問,Android N上插著usb,然后執(zhí)行echo mem >sys/power/state,可以看到屏幕背光滅了,但是cat proc/kmsg log:<6>[ 3769.251077][2016-01-03 20:36:55.759322763]PM: suspend entry 2016-01-03 20:36:55.745081096 UTC

<6>[ 3769.259538][2016-01-03 20:36:55.839104013]PM: Syncing filesystems ... done.

<7>[ 3769.339710][2016-01-03 20:36:55.839118492]PM: Preparing system for mem sleep

<6>[ 3769.581798][2016-01-03 20:36:56.122554950]Restarting tasks ... done.

<6>[ 3769.620337][2016-01-03 20:36:56.122567710]PM: suspend exit 2016-01-03 20:36:56.114344950 UTC

不明白屏幕為什么會滅,手動寫節(jié)點,在freeze task被終止suspend,沒處理到device啊

另外,終止suspend的原因是usb鎖沒釋放嗎,我看wake_lock節(jié)點下有PowerManagerService.Display和PowerManagerService.WakeLocks這兩個鎖

2016-10-20 19:51

@cracker:1. 是的。

2. 為什么屏幕背光毀滅?我猜在freeze task的時候,有些task主動關(guān)的背光,不過具體是怎么回事,你可以再查查。至于suspend失敗的原因,應(yīng)該是電源管理服務(wù)的鎖----PowerManagerService.WakeLocks(因為你現(xiàn)在在充電)。另外你可以看看這個文件,它有很多統(tǒng)計信息:

/sys/kernel/debug/suspend_stats

漢紙月

2016-08-26 16:58

@wowo

有一事不明,請教老師,主要就是內(nèi)核都睡下去了,如何才醒得過來:

假設(shè)是STR,在函數(shù)suspend_enter中,最終調(diào)用如下函數(shù)進(jìn)入了睡眠中。

error = suspend_ops->enter(state);

當(dāng)函數(shù)返回的時候,睡眠就結(jié)束了,開始了resume的過程。

這個suspend_ops->enter(state);中做了些什么事情呢?它怎么能突然就醒了呢?

syscore_suspend()函數(shù)似乎是在irq禁止的情況下調(diào)用的。所以suspend_ops->enter(state)這個里面,中斷是不是也禁止了?

就算中斷沒有禁止,中斷處理器和這個函數(shù)處于兩個執(zhí)行線程中,如何從中斷處理器中通知suspend_ops->enter(state)有wakeup事件需要醒過來呢?

能以ARM為例介紹一下嗎?非常感謝老師了。

2016-08-26 17:26

@漢紙月:你可以這樣認(rèn)為:

當(dāng)CPU執(zhí)行完syscore_suspend中的某一個指令后,它就停止工作了。直到外設(shè)(例如GIC,它還活著)給它發(fā)送一個硬件的wakeup信號,它就醒了,繼續(xù)執(zhí)行,suspend_ops->enter返回。

具體可以看看下面大家的評論和討論。

aaron

2016-04-18 16:36

你好,請教一個問題。

先介紹一下背景,android4.4+kernel3.10

我們設(shè)計要求是當(dāng)用戶按下電源按鍵(用戶請求系統(tǒng)休眠)時,系統(tǒng)必須無條件進(jìn)入休眠。但用戶再次按下電源鍵時必須無條件喚醒系統(tǒng)。

目前我們我們修改了powermanger中wakelock的機(jī)制保證滿足我們的設(shè)計要求。

現(xiàn)在測試發(fā)現(xiàn)一個問題:有時候用戶按電源鍵試圖喚醒系統(tǒng)時,并沒有將系統(tǒng)喚醒。通過log分析發(fā)現(xiàn)當(dāng)用戶按下電源鍵時,內(nèi)核已經(jīng)被喚醒了,但是緊接著又進(jìn)入了suspend過程。

現(xiàn)在不清楚是什么原因。

2016-04-18 17:04

@aaron:首先,我覺得,“無條件休眠”這種設(shè)計,有點粗暴,不妥。kernel的suspend過程,需要很多同步操作,這樣做,可能會有一些問題。

然后是你的問題,很明顯,兩次power key按下之間,沒有同步好,每次power key按下被處理的時候,需要嚴(yán)格依賴當(dāng)前的狀態(tài)(以便執(zhí)行toggle動作)。例如,當(dāng)power key按下后:

如果系統(tǒng)正在執(zhí)行suspend,要怎么辦?

如果系統(tǒng)正在執(zhí)行resume,要怎么辦?

2015-08-03 16:38

打擾了,wowo請教一個問題,當(dāng)進(jìn)入enter之前中斷已經(jīng)被關(guān)閉了,CPU進(jìn)入suspend后,這里的wakeup event是指什么呢?CPU是靠什么東西來捕獲的自動恢復(fù)的?

2015-08-03 21:42

@銳:這個問題可以參考“http://www.wowotech.net/linux_kenrel/suspend_and_resume.html”中l(wèi)inuxer同學(xué)的回答。

2015-08-04 14:46

@wowo:謝謝wowo,看了解釋,受益匪淺,但還有一點不太明白,linuxer說:

GIC和各個CPU的接口包括兩種硬件信號:

(a)觸發(fā)CPU中斷的信號。nIRQCPU和nFIQCPU信號線,熟悉ARM CPU的工程師對這兩個信號線應(yīng)該不陌生,主要用來觸發(fā)ARM cpu進(jìn)入IRQ mode和FIQ mode。

(b)Wake up信號。nFIQOUT和nIRQOUT信號線,去ARM CPU的電源管理模塊,用來喚醒CPU的

因此disable了CPU的中斷僅僅是堵死了中斷這一個分支而已,wakeup信號仍在正常工作中。

當(dāng)CPU休眠的時候,中斷關(guān)閉的時候,wakeup信號怎么才能產(chǎn)生呢?比如:外部一個按鍵按鈕按下或者點擊觸摸屏的時候,GIC捕獲到wakeup信號了?

在系統(tǒng)suspend之后,捕獲這種特定信號來喚醒,在driver里注冊中斷是不是加入IRQF_NO_SUSPEND這個標(biāo)識就可以做到了?

2015-08-04 15:19

@銳:是的,GIC沒有睡死,如果加入IRQF_NO_SUSPEND,就會保留這個設(shè)備和GIC之間的聯(lián)系。

2015-08-06 17:45

@wowo:wowo,你好,非常感謝你的分享。按照CPU進(jìn)入休眠狀態(tài)的說法,是不是也就說現(xiàn)在的安卓系統(tǒng)鎖屏,基本上都不會進(jìn)入suspend的狀態(tài),就像類似于推送服務(wù)一樣,它需要捕獲網(wǎng)絡(luò)發(fā)送過來的消息,都獲取了wakelock,阻止系統(tǒng)進(jìn)入了休眠,程序一直在后臺運(yùn)行不是比較耗電嗎?

2015-08-06 18:23

@銳:網(wǎng)絡(luò)消息不需要實時啊,定時去取就行了,所以還是會suspend的。

2015-06-30 20:13

注意這個變量,events_check_enabled,如果它不為真,pm_wakeup_pending接口直接返回false,意味著如果不利用wakeup count功能,suspend過程中不會做任何wakeup events檢查,也就不會進(jìn)行任何的同步。

------如果events_check_enabled不為真的話,應(yīng)該不會跑到pm_wakeup_pending的吧。會發(fā)生wakeup_count_store回寫錯誤,用戶空間進(jìn)程被終止。所以"也就不會進(jìn)行任何的同步"不會存在這種情況的吧。

2015-06-30 20:17

@koala:所以,只要跑到pm_wakeup_pending時,events_check_enabled肯定會被置1的,不然pm_wakeup_pending返回0,suspend_ops->enter(state)一定會被執(zhí)行。

2015-06-30 21:28

@koala:可能您理解錯我的意思了,/sys/power/state可以在不操作wakeup count的前提下使用的,在這種情況下,suspend過程會跑到pm_wakeup_pending,由于events_check_enabled為false,則不會進(jìn)行任何的檢查,繼續(xù)suspend過程。

其實這就是傳統(tǒng)suspend的方法,即不依賴wakeup count時的方法,此時kernel不會做任何同步處理。

1 2

發(fā)表評論:

昵稱

郵件地址 (選填)

個人主頁 (選填)

總結(jié)

以上是生活随笔為你收集整理的Linux中_countof函数,Linux电源管理(8)_Wakeup count功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。