天天看點

wake lock/ wake unlock 應用

如果給一個需要鎖的驅動,添加一把鎖呢?

和android上層看到的鎖類似,鎖有逾時鎖與非逾時鎖兩種。逾時鎖我們以USB為例

需要包含的頭檔案:#include <linux/wakelock.h>

在初始化函數或者_probe函數中,

[csharp]  view plain copy

  1. wake_lock_init(&usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect");  

這樣就注冊上一個name為"usb_detect"的鎖,此鎖屬性是WAKE_LOCK_SUSPEND,差別與WAKE_LOCK_IDLE。

在鎖的初始化上,是不區分逾時鎖與非逾時鎖的,而是在申請與釋放鎖。

我們下面申請一個逾時鎖,目的是在USB拔掉之後幾秒時間内,系統不要進入深度睡眠。

[csharp]  view plain copy

  1. static irqreturn_t usb_detect_irq_handler(int irq, void *dev_id)  
  2. {  
  3.     wake_lock_timeout(&usb_wakelock, 3 * HZ);//3秒的逾時時間  
  4.     schedule_delayed_work(&wakeup_work, HZ / 10);  
  5.     return IRQ_HANDLED;  
  6. }  

在拔掉和插入USB後,會出發這個handler,進而申請 "usb_detect"的逾時鎖,逾時時間是3秒,3秒後,自動釋放這個鎖。

可以在序列槽輸入cat proc/wakelocks檢視目前系統所有鎖情況。

非逾時鎖,需要手動申請,手動釋放,而且需要注意比對使用申請與釋放。我們以alarm為例,

Alarm Manager 

AlarmManage有一個AlarmManagerService,該服務程式主要維護app注冊下來的各類Alarm,并且一直監聽Alarm裝置,一旦有Alarm觸發,或者是Alarm事件發生,AlarmManagerService就會周遊Alarm清單,找到相應的注冊Alarm并發出廣播

Alarm Manager會維持一個cpu的wake lock。這樣能保證電話休眠時,也能處理alarm的廣播。一旦alarm receiver的onReceive() 方法執行完,wake lock會迅速被釋放。如果在receiver中開啟一個service,有可能service還沒啟動,wake lock已經被釋放了。是以此時要實作單獨的wake lock政策。

有4種Alarm類型: 

1)RTC_WAKEUP 

在指定的時刻(設定Alarm的時候),喚醒裝置來觸發Intent。

2)RTC 

在一個顯式的時間觸發Intent,但不喚醒裝置。   

3)ELAPSED_REALTIME 

從裝置啟動後,如果流逝的時間達到總時間,那麼觸發Intent,但不喚醒裝置。流逝的時間包括裝置睡眠的任何時間。注意一點的是,時間流逝的計算點是自從它最後一次啟動算起。   

4)ELAPSED_REALTIME_WAKEUP 

從裝置啟動後,達到流逝的總時間後,如果需要将喚醒裝置并觸發Intent。 

同樣,先在_probe中初始化一個鎖

[csharp]  view plain copy

  1. wake_lock_init(&hym8563->wake_lock, WAKE_LOCK_SUSPEND, "rtc_hym8563");  

在_remove中反初始化

[csharp]  view plain copy

  1. wake_lock_destroy(&hym8563->wake_lock);  

然後在set_alarm的時候,申請鎖

[csharp]  view plain copy

  1. wake_lock(&hym8563->wake_lock)  

在alarm結束後釋放這個鎖

[csharp]  view plain copy

  1. wake_unlock(&hym8563->wake_lock)

用ec43_GPIO的中斷來喚醒系統,将系統從深度休眠中喚醒并保證系統wakup 一段時間用過了,方法如下,有同樣使用的童鞋可以參考一下! 1.   定義一人局部靜态變量 ec43_wlock: static struct wake_lock ec43_wlock; 2. 初始化  wake_lock: wake_lock_init(&ec43_wlock, WAKE_LOCK_SUSPEND, "ec43_wakelock"); 3.在需要喚醒處調用: wake_lock_timeout(&ec43_wlock, msecs_to_jiffies(10*1000));                         作用同上,詳細不再說明,自己檢視 //wake_lock_timeout(&ec43_wlock, 10*HZ); 4. remove中移除該waku_lock: wake_lock_destroy(&ec43_wlock);