RTC子係統內核文檔
============================================
譯者:yuanlulu
https://blog.csdn.net/yuanlulu
版權沒有,但是轉載請保留此段聲明
============================================
RTC內核文檔 英文原文地址:https://lxr.linux.no/linux+v2.6.38/Documentation/rtc.txt
用戶空間使用RTC的例程在:https://lxr.linux.no/linux+v2.6.38/Documentation/rtc.txt#L216
Real Time Clock (RTC) Drivers for Linux
=======================================
Linux有兩個基本兼容的用戶空間RTC API家族:
*/dev/rtc 這是PC係統提供的兼容接口,不適用於非x86的係統
*/dev/rtc0 /dev/rtc1 這是大部分係統支持的形式。
雖然所有的RTC適用同樣的API和RTC架構交互,但是硬件提供的功能並不一樣。
比如不是所有的RTC都產生中斷,所以它們不能做鬧鍾定時。
(在fedora 上/dev/rtc是一個指向/dev/rtc0的鏈接)
老式PC/AT兼容驅動:/dev/rtc
----------------------------------------
/dev/rtc(主設備號10,次設備號135,隻讀字符設備)的中斷以unsigned int的格式報告。最低的兩字節包含中斷類型(update-done, alarm-rang, or periodic),
剩下的字節包含自上次讀取以來中斷的次數。如果使能了proc文件係統,在/proc/driver/rtc下能讀到中斷的狀態信息。由於驅動占有了鎖,所以同一時間隻能有
一個進程占有/dev/rtc。
用戶進程可以使用read(2)或者select(2)監視/dev/rtc-它們都將阻塞在設備節點上直到下一個中斷的到來。
隻有root用戶能在dev/rtc上使用大於64HZ的中斷。這個值可以通過往/proc/sys/dev/rtc/max-user/freq寫入新的值來改變。記住中斷處理函數應該盡可能簡短。
內核使用額外的代碼來和RTC進行同步-內核每11分鍾就將自己的時間寫回CMOS。在回寫的時候內核會關閉RTC的周期中斷,
所以依賴RTC周期中斷的重要工作需要特別注意這一點。如果你的內核不和RTC進行同步,內核不會訪問RTC,你可以把RTC做其它的用處。
中斷的頻率是通過ioctl(2)調用/include/linux/rtc.h中的命令來設置的。
新式的“RTC class”接口:/dev/rtcN
----------------------------------------------
由於linux支持的一些非ACPI和非PC平台有不止一個RTC,所以需要更具有可移植性的解決方案。
一種新的“RTC類”框架就是為此而生的,它支持三類用戶空間接口:
*/dev/rtcN 和老式的/dev/rtc接口大體相同。
*/sys/class/rtc/rtcN sysfs支持隻讀的訪問RTC屬性。
*/proc/driver/rtc 第一個RTC(rtc0)可以從procfs中暴露自己的更多信息(比sysfs多)。
新的RTC class框架支持多種RTC,包括片上RTC和使用i2c、spi等接口的獨立芯片。甚至支持在最新
的PC上通過ACPI暴露的特性。
新的框架不再受"每個係統一個RTC”的約束。比如係統中可以有一個電池供電的低功耗i2c RTC芯片
和一個高性能的片上RTC。係統可以從外置的RTC讀取時間,其它的任務或許需要從高性能的片內RTC。
SYSFS 接口
------
sysfs接口在/sys/class/rtc/rtcN 下,可以直接訪問。所有的數據和時間都是RTC的時區決定的,
而不是係統時間的時區
date: 日期:年月日
hctosys: 1:RTC在係統啟動的時候通過CONFIG_RTC_HCTOSYS設置係統時間
0:其它
max_user_freq: 一般用戶(不是root)能從RTC申請的最大中斷速率。
name: 映射到這個目錄的RTC的名字
since_epoch: 和c函數time返回的值意義是一樣的。
time: 時分秒。
wakearm: 下一次係統喚醒事件的時間點。這個喚醒事件是一次性的,所以要多次喚醒的話需要在每次
喚醒後重新設置。格式是下次喚醒的 since_epoch值,或者在開頭有一個“+”號的話,表示
未來多少秒後發生喚醒事件。
IOCTL接口
--------------
/dev/rtc支持的ioctl()接口同樣支持新的RTC框架。
* RTC_RD_TIME, RTC_SET_TIME 讀取和設置時間。傳遞時間的參數是struct
rtc_time結構體。
* RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ alarm中斷的開啟、關閉、設置、讀取。
如果RTC和某個中斷線相連,它可以在未來24小時內的某個時間段內產生中斷。
(建議優先使用RTC_WKALM_*)
* RTC_WKALM_SET, RTC_WKALM_RD 設置和讀取 wakeup alarm觸發的時間點。wakeup alarm和alrm
中斷唯一不同的是wakeup alrm可以申請超過24小時的定時中斷。
* RTC_UIE_ON, RTC_UIE_OFF 更新中斷,每秒鍾觸發一次(更新的時候觸發,因此每秒一次)。
* RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ 周期中斷的開啟、關閉、設置、讀取。
周期中斷的頻率必須是2^N(N>= 1),大於64的頻率隻有root用戶才能設置。
(RTC_AIE_ON, RTC_AIE_OFF可以開啟和關閉alarm和wake alarm的功能)
yuanlulu的補充:
* RTC_RD_TIME, RTC_SET_TIME的參數是一個struct rtc_time的指針。它的各個成員的含義和struct
tm是一樣的。
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;
unsigned char pending; /* 0 = alarm not pending, 1 = alarm pending */
struct rtc_time time; /* time the alarm is set to */
};
};
隻是wake_alarm沒有時間限製,可以指定未來任意時刻發生中斷。
struct rtc_wkalrm {
unsigned char enabled; /* 0 = alarm disabled, 1 = alarm enabled */unsigned char pending; /* 0 = alarm not pending, 1 = alarm pending */
struct rtc_time time; /* time the alarm is set to */
};
* RTC_ALM_SET, RTC_ALM_READ 的傳遞參數也是struct
rtc_time的指針,但隻有時分秒的部分有效。時分秒
這三個成員代表24小時以內的時間點。比如當前時間是13:00:00,而傳入的參數是14:00:00,則意味著定時中斷
將在一小時後發生。而如果傳入的參數是12:00:00,則意味著明天中午發生中斷。總之,alarm 中斷不能超過
24小時。
*
RTC_IRQP_SET, RTC_IRQP_READ 周期中斷的參數是中斷頻率,參數必須是2^N(N>=1),也就是說
設置的周期中斷必須大於2。並且隻有root用戶可以設置64HZ以上的頻率。
RTC的中斷方式有三類:
1.更新中斷,也就是RTC的時間更新的時候觸發的中斷。RTC每秒鍾更新一次,所以更新中斷的頻率就是1。
2.周期中斷。頻率可以設置為2^N(N>=1)。注意周期中斷頻率不可設置為1,否則會被忽略。
3. alarm/wake alarm。這兩個中斷內部實現是一樣的,隻不過前者隻能指定24小時內的某一時刻觸發中斷,後者沒有限製。
中斷被觸發後,可以從RTC設備節點中讀取到一個unsigned long數據,最低兩比特表示中斷的類型。各bit的定義如下:
/* interrupt flags */
#define RTC_IRQF 0x80 /* any of the following is active */
#define RTC_PF 0x40 //周期中斷
#define RTC_AF 0x20 //定時中斷(alarm和wakeup alarm中斷)
#define RTC_UF 0x10 //更新中斷
#define RTC_IRQF 0x80 /* any of the following is active */
#define RTC_PF 0x40 //周期中斷
#define RTC_AF 0x20 //定時中斷(alarm和wakeup alarm中斷)
#define RTC_UF 0x10 //更新中斷
再說RTC中斷:RTC的中斷概念和內核中的中斷不是一回事,沒有中斷回調函數。但是在設備節點上使用select和read
睡眠的函數會被喚醒,這就是RTC中斷的功能。
另外RTC的設備節點,同一時刻隻允許一個用戶打開。不可能兩個用戶同時打開同一個RTC設備設備節點。
經過測試,有以下結論:
1.更新中斷(1HZ)和周期中斷可以同時開啟。
2.周期中斷可以和alarm中斷同時開啟。
3.alarm中斷不可以和wakeup alarm中斷同時開啟,因為他們兩個在內核中就是一回事。
4..RTC_WKALM_SET不必設置struct
rtc_wkalrm的enabled成員,隻在讀取的時候才需要這個成員。
猜測:更新中斷和可以和alarm中斷同時開啟。
從RTC設備節點讀取到的數據,包含了上次讀取以來發生中斷的次數(包括所有類型的中斷)。
低字節會置位發生的所有中斷類型。
最後更新:2017-04-03 18:51:50