1. 程式人生 > >Linux時間子系統之二:Alarm Timer

Linux時間子系統之二:Alarm Timer

數據 類型 oid mtime orm 分別是 type mon 超時

一、前言

嚴格來講Alarm Timer也算POSIX Timer一部分,包含兩種類型CLOCK_REALTIME_ALARM和CLOCK_BOOTTIME_ALARM。分別是在CLOCK_REALTIME和CLOCK_BOOTTIME後面加上_ALARM。Alarm Timer之外的POSIX Timer在內核進入cpuidle或者suspend之後,都會因為省電關閉ClockEvent設備而停止計時。而Alarm Timer恰恰借助RTC設備的長供電且具備喚醒功能,在系統進入suspend過程中,將最近一次超時expires寫入RTC設備,超時後會將系統從suspend狀態喚醒,執行timer超市函數。

這樣在程序執行過程中,就不需要一直持有wakelock。

二、背景介紹

Alarm Timer可以說工作在兩種狀態下,一種是和其他Timer一樣的基於hrtimer;另一種是在系統進入suspend後基於RTC設備。

RTC設備在系統外獨立供電,RTC具備Alarm功能。在Alarm觸發後,通過中斷喚醒suspend的系統。

在device_initcall-->alarmtimer_init時,註冊一個alarmtimer的platform_device,驅動為alarmtimer_driver。將alarmtimer_suspend作為鉤子函數插入系統suspend流程,這樣就將suspend和Alarm Timer功能掛鉤了。

三、重要數據結構

struct alarm_base作為AlarmTimer時鐘類型結構體,包含ALARM_REALTIME和ALARM_BOOTTIME兩種。

static struct alarm_base {
  spinlock_t lock;---------------------------------互斥訪問鎖
  struct timerqueue_head timerqueue;-------AlarmTimer自己維護了expires紅黑樹。
  struct hrtimer timer;--------------------------將其加入到hrtimer_bases對應的紅黑樹中。
  ktime_t (*gettime)(void);--------------------獲取對應類型時鐘的時間函數
  clockid_t base_clockid;------------------------時鐘類型ID,CLOCK_REALTIME和CLOCK_BOOTTIME
} alarm_bases[ALARM_NUMTYPE];

CLOCK_REALTIME_ALARM和CLOCK_REALTIME、CLOCK_BOOTTIME_ALARM和CLOCK_BOOTTIME都是用同樣的base_clockid,但是_ALARM維護的alarm_bases[ALARM_NUMTYPE].timerqueue將他們與其他hrtimer區分開了。

struct k_clock alarm_clock作為兩種類型共用的時鐘/Timer函數:

struct k_clock alarm_clock = {
  .clock_getres = alarm_clock_getres,
  .clock_get = alarm_clock_get,
  .timer_create = alarm_timer_create,
  .timer_set = alarm_timer_set,
  .timer_del = alarm_timer_del,
  .timer_get = alarm_timer_get,
  .nsleep = alarm_timer_nsleep,
};

static struct rtc_timer rtctimer;--------------------RTC Timer

static struct rtc_device *rtcdev;-------------------RTC設備對應的結構體

struct rtc_time是RTC設備表示的時間格式:

struct rtc_time {
  int tm_sec;
  int tm_min;
  int tm_hour;
  int tm_mday;
  int tm_mon;
  int tm_year;
  int tm_wday;
  int tm_yday;
  int tm_isdst;
};

struct ktime_t是內核時間格式。

這兩種時間格式的轉換,rtc_time到ktime_t通過rtc_tm_to_ktime;ktime_t到rtc_time通過rtc_ktime_to_tm。

四、AlarmTimer正常工作狀態下運行

五、AlarmTimer在進入Suspend時、Suspend中、Resume時狀態分析

Linux時間子系統之二:Alarm Timer