Updated: 2013/03/18, 剛有時間瀏覽了最新的Android builder submit 2013的相關slides,其中有關於最新的android 對kernel的upstream的狀態的總結,大家可以看看
http://events.linuxfoundation.org/images/stories/slides/abs2013_stultz.pdf
Alarm正在staging中,不久應該也會進入main stream
Alarm是Android提供的一個硬件時鐘,基於內核的rtc機制完成.
相關知識點:
內核中的各種時間函數
ktime_get_ts 參見POSIX.1b clock types, 可以從<The Linux Programming Interface>的第23.5.1找到相應說明
當應用程序希望不會受到手動的改變系統時鐘的影響時最有用.在Linux中,這個時間反應了從系統啓動開始流逝的時間.
getnstimeofday 類似與user space的gettimeofday, 反映的是從1970年開始的毫秒還有一些各種時間格式之間的轉換函數在timer.c
一些有用的資源,在需要用到時鐘那進行控制的事情,一定要記着選擇正確的精度和函數,並多參考現有的其它driver.
Documentation/timers/timers-howto.txt關於driver初始化的優先級http://www.ibm.com/developerworks/linux/library/l-timers-list/index.html?ca=drs-
http://stackoverflow.com/questions/4655711/measuring-execution-time-of-a-function-inside-linux-kernel
http://stackoverflow.com/questions/6360210/androidlinux-uptime-using-clock-monotonic其中提到了最新引入內核的CLOCK_BOOTTIME.
https://lwn.net/Articles/429925/ 全面介紹了最新的內核中時鐘的概念, 也提到了Android的alarm timer的實現分爲兩個層次:initcall, Makefile.同樣的initcal中以Makefile中的順序排序,如果不在同一個initcall的層次,則以initcall的順序調用. initcal的順序參見init.h...
#define late_initcall(fn) __define_initcall("7",fn,7)..
關於alarm的一些總體認識和定義,參照include/linux/android_alarm.h中的描述:
alarm提供的接口與hrtimer的接口類似,增加了從suspend狀態wakeup的功能.並且提供了一個給週期性timer使用的遞減的實時時鐘,確保它在系統suspend的時候或者當wall time被改變的時候依然能夠繼續工作.
作爲platform驅動被platform_driver_register所註冊.
使用了WAKE_LOCK_SUSPEND的wake lock來保證在系統不會進入full的suspend狀態,從而能夠提供比較好的低延遲.
Android的alarm提供了兩個設備一個alarm的platform driver(alarm.c)
關於platform driver的相關理解參見<Device Driver學習之platform driver是神馬>
其中值得注意的是, 它通過rtc_alarm_interface這個一個class interface,使得alarm使用了rtc提供的一些接口. 這裏使用msm_rtc這個rtc設備作爲alarm設備的時鐘源.這裏就體現了一個重要的知識點,如何使用既有的設備構建新的設備(即,使用class_interface提供的機制,使得platform alarm設備在msm_rtc設備被添加到system的時候,通過platform的core通知到platform alarm設備class_interface的add_dev,然後把platform alarm設備註冊入添加到系統中)!!!
Class Device http://www.linuxjournal.com/node/6872/print, 這篇文章雖然有點老,但是對於基本概念還是闡述的挺好的.# dmesg | grep "using rtc device"
<6>[ 7.471466] using rtc device, msm_rtc, for alarms
<6>[ 7.471618] rs30000048:00010000 rs30000048:00010000: rtc core: registered msm_rtc as rtc0
一個暴露給用戶使用的接口misc的alarm接口(alarm-dev.c)
其中定義了一些列的ioctl,來操縱platform alarm driver提供的功能.
哪些地方使用到了alarm提供的接口:
通過grep android的代碼,如下地方使用了alarm的user接口:
development/simulator/wrapsim/FakeDev.c: * /dev/alarm
frameworks/base/cmds/runtime/main_runtime.cpp: fd = open("/dev/alarm", O_RDWR);
frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp: return open("/dev/alarm", O_RDWR);
frameworks/base/libs/utils/SystemClock.cpp: fd = open("/dev/alarm", O_RDWR);
frameworks/base/libs/utils/SystemClock.cpp: int fd = open("/dev/alarm", O_RDONLY);system/core/toolbox/date.c: fd = open("/dev/alarm", O_RDWR);
system/core/toolbox/date.c: fd = open("/dev/alarm", O_RDWR);
system/core/toolbox/uptime.c: fd = open("/dev/alarm", O_RDONLY);
system/core/toolbox/alarm.c: afd = open("/dev/alarm", O_RDWR);
system/core/rootdir/ueventd.rc:/dev/alarm 0664 system radio
用戶層可以使用的由alarm驅動提供的四種硬件時鐘:
RTC_WAKEUP(ANDROID_ALARM_RTC_WAKEUP):在指定的時刻(設置Alarm的時候),喚醒設備來觸發Intent。
RTC(ANDROID_ALARM_RTC):在一個顯式的時間觸發Intent,但不喚醒設備。
ELAPSED_REALTIME(ANDROID_ALARM_ELAPSED_REALTIME):從設備啓動後,如果流逝的時間達到總時間,那麼觸發Intent,但不喚醒設備。流逝的時間包括設備睡眠的任何時間。注意一點的是,時間流逝的計算點是自從它最後一次啓動算起。ELAPSED_REALTIME_WAKEUP(ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP):從設備啓動後,達到流逝的總時間後,如果需要將喚醒設備並觸發Intent。
以上4個時鐘都是通過alarm service提供給用戶使用的,它們通過對應的JNI側()來獲得alarm驅動提供的硬件時鐘.
還有一個在alarm驅動中定義的硬件時鐘是ANDROID_ALARM_SYSTEMTIME, 它沒有暴露給java層的用戶來使用. 它是返回上文所提到的ktime_get_ts函數返回的值.目前還沒有用戶側的程序需要使用它.
另外,值得注意的是Android提供了對alarm設備的測試程序(mydroid/system/core/toolbox/alarm.c), 但是,沒有放在編譯的Android.mk中,所以需要修改toolbox的Android.mk才能把它編譯出來.