
??想了解更多關(guān)于開源的內(nèi)容,請?jiān)L問:??
??51CTO 開源基礎(chǔ)軟件社區(qū)??
??https://ost.51cto.com??
1、RTC介紹
RTC是Real Time Clock的簡稱,它在硬件電路上單獨(dú)供電,當(dāng)系統(tǒng)關(guān)機(jī)時(shí),CPU和其他外部硬件設(shè)備全部掉電,但是RTC仍然繼續(xù)工作。這樣就可以繼續(xù)給設(shè)備提供精準(zhǔn)的時(shí)鐘,并提供報(bào)警功能和計(jì)時(shí)器功能。
2、如何查詢系統(tǒng)時(shí)間和硬件時(shí)間
(1)查詢系統(tǒng)時(shí)間.
# dateSat Aug 5 09:15:26 UTC 2017
(2)查看RTC硬件時(shí)間:hwclock -r 顯示RTC時(shí)間(讀取RTC時(shí)間顯示)。
# hwclockSat Aug 5 09:13:36 2017 0.000000 seconds
(3) 設(shè)置系統(tǒng)時(shí)間,硬件時(shí)間hwclock -r 顯示RTC時(shí)間(讀取RTC時(shí)間顯示)hwclock -w 設(shè)置RTC時(shí)間(將系統(tǒng)時(shí)間傳遞給RTC驅(qū)動(dòng),設(shè)置RTC的驅(qū)動(dòng)時(shí)間)hwclock -s 設(shè)置系統(tǒng)時(shí)間(將RTC時(shí)間讀取出來設(shè)置給系統(tǒng)時(shí)間).
3、如何查看RTC設(shè)備節(jié)點(diǎn)及文件
(1)RTC設(shè)備節(jié)點(diǎn)。
# pwd
/dev# ls rtc*
rtc rtc0 rtc1
2)sys/class/rtc
# pwd
/sys/class/rtc# ls
rtc0 rtc1# pwd
/sys/class/rtc/rtc0# ls
alarmtimer.3.auto device name subsystem wakealarm
date hctosys power time
dev max_user_freq since_epoch uevent
(2)proc/driver/rtc:獲取RTC的相關(guān)信息。
# cat proc/driver/rtc
rtc_time : 09:12:46
rtc_date : 2017-08-05
alrm_time : 00:00:00
alrm_date : 1999-12-16
alarm_IRQ : no
alrm_pending : no
update IRQ enabled : no
periodic IRQ enabled : no
periodic IRQ frequency : 1
max user IRQ frequency : 64
24hr : yes
4、內(nèi)核中如何開啟RTC,并設(shè)置時(shí)間同步
在linux系統(tǒng)上,從用戶空間正確管理RTC需要關(guān)注兩個(gè)內(nèi)核選項(xiàng):CONFIG_RTC_HCTOSYSCONFIG_RTC_HCTOSYS_DEVICE要使用CONFIG_RTC_HCTOSYS應(yīng)在內(nèi)核構(gòu)建過程中包含代碼文件drivers/rtc/hctosys.c,它在啟動(dòng)和恢復(fù)時(shí)從RTC設(shè)置系統(tǒng)時(shí)間。一旦啟用此選項(xiàng),就將使用從指定RTC設(shè)備讀取的值設(shè)置系統(tǒng)時(shí)間。RTC設(shè)備應(yīng)該在CONFIG_RTC_HCTOSYS_DEVICE中指定:
CONFIG_RTC_HCTOSYS=yCONFIG_RTC_HCTOSYS_DEVICE="rtc0"
5、RTC關(guān)鍵結(jié)構(gòu)體說明
rtc_time 結(jié)構(gòu)體說明:
struct rtc_time {
inttm_sec; /* 秒,0~60(60是閏秒的需要)*/
inttm_min; /* 分鐘,0~59*/
inttm_hour; /* 小時(shí),0~23 */
inttm_mday; /* 本月中的第幾天,1~31 */
inttm_mon; /* 自一月以來的第幾個(gè)月,0~11*/
inttm_year; /* 自1900年以來的年數(shù)*/
inttm_wday; /* 本周的第幾天,0~6,星期天是0 */
inttm_yday; /* 一年當(dāng)中的第幾天,0~365*/
inttm_isdst; /* 夏令時(shí)標(biāo)志*/
};
rtc_wkalrm 結(jié)構(gòu)體說明:
struct rtc_wkalrm {
unsignedchar enabled; /* 0 = 禁止alarm,1 = 使能alarm */
unsignedchar pending; /* 0 = alarm未掛起,1 = alarm掛起(已發(fā)生)*/
structrtc_time time; /* 設(shè)置的alarm中斷發(fā)生的時(shí)刻 */
};
6、RTC框圖

7、RTC適配問題總結(jié)
問題1:/dev/rtc未生成,無法獲取硬件時(shí)間。
# hwclock
hwclock: /dev/misc/rtc: No such file or directory
問題分析:啟動(dòng)日志報(bào)錯(cuò)no valid clock/calendar values available
[ 1.179936] rk808-rtc rk808-rtc: registered as rtc0[ 1.186459] rtc-hym8563 5-0051: no valid clock/calendar values available[ 1.186675] rtc-hym8563 5-0051: registered as rtc1[ 1.187698] rtc-hym8563 5-0051: no valid clock/calendar values available[ 1.187723] rtc-hym8563 5-0051: hctosys: unable to read the hardware clock
從log分析,rtc1時(shí)鐘值無效,可能為人為寫入了無效值,或者初始化時(shí)寫入了無效值;解決方案:
(1)在dts中添加init_date項(xiàng),當(dāng)hym8563_probe的時(shí)候,檢測到系統(tǒng)如果未設(shè)置時(shí)間,則給時(shí)鐘芯片一個(gè)默認(rèn)值(init_date 設(shè)置的值);
&i2c_AO {
status = "okay";
pinctrl-names="default";
pinctrl-0=;
clock-frequency = ; /* default 100k */
/* for rtc hym8563 */ hym8563: hym8563@51 {
compatible = "haoyu,hym8563";
reg = ;
init_date = "2021/07/28";
#clock-cells = ;
};
};
(2)通過命令設(shè)置硬件時(shí)鐘;
hwclock -w。
驗(yàn)證結(jié)果:通過日志查看顯示.
[ 1.413453] rk808-rtc rk808-rtc: registered as rtc0
[ 1.423286] rtc-hym8563 5-0051: registered as rtc1
[ 1.424348] rtc-hym8563 5-0051: setting system clock to 2021-11-13T21:10:55 UTC (1636837855)
問題2:將rtc1設(shè)置為硬件時(shí)鐘后,連接網(wǎng)絡(luò)進(jìn)行NTP時(shí)間同步,查看rtc1時(shí)鐘未同步,實(shí)際同步的是rtc0硬件時(shí)鐘
# dateFri Nov 18 15:53:21 UTC 2022# hwclockSun Nov 14 20:18:58 2021 0.000000 seconds
問題分析:懷疑連接網(wǎng)絡(luò)后,網(wǎng)絡(luò)時(shí)間同步模塊在將同步后的系統(tǒng)時(shí)間寫入硬件時(shí)鐘時(shí),寫入到了/dev/rtc0,而非實(shí)際使用的/dev/rtc1;經(jīng)排查網(wǎng)絡(luò)時(shí)間同步后設(shè)置硬件時(shí)鐘代碼所在位置為:/base/miscservices/time/services/time_manager/src/time_service.cpp加入LOG打印信息如下,證實(shí)問題所在就是寫入到了/dev/rtc0,而非實(shí)際使用的/dev/rtc1;
# hilog | grep RTC
11-18 15:46:28.906 464 464 E 01c02/TimeService: [time_service.cpp] set_rtc_time# RTC rtc_id : 0:
11-18 15:46:28.906 464 464 E 01c02/TimeService: [time_service.cpp] set_rtc_time# RTC rtc_dev : /dev/rtc0:
解決方案:修改代碼set_rtc_time函數(shù)中,設(shè)備節(jié)點(diǎn)由/dev/rtc0修改為/dev/rtc,此時(shí)/dev/rtc軟連接的是實(shí)際使用的硬件時(shí)鐘/dev/rtc1,而非固定為/dev/rtc0。
vi base/miscservices/time/services/time_manager/src/time_service.cpp +351
@@ -348,13 +356,15 @@ int TimeService::set_rtc_time(time_t sec)
return -1;
}
std::stringstream strs;
- strs << "/dev/rtc" << rtc_id;
+ strs << "/dev/rtc";
修改后發(fā)現(xiàn)NTP時(shí)鐘同步仍然失敗,加log打印后發(fā)現(xiàn),set_rtc_time中open設(shè)備節(jié)點(diǎn)失敗。
11-18 17:10:41.495 533 533 E 01c02/TimeService: [time_service.cpp] set_rtc_time# RTC rtc_dev : /dev/rtc:11-18 17:10:41.495 533 533 E 01c02/TimeService: [time_service.cpp] set_rtc_time# RTC open failed /dev/rtc: Permission denied
查看設(shè)備節(jié)點(diǎn)發(fā)現(xiàn),新增的rtc1用戶組為root,因此用戶程序無權(quán)限打開,需將用戶組修改為system。
# ls -al rtc*
lrwxrwxrwx 1 root system 4 2021-11-14 21:15 rtc -> rtc1
crw-r----- 1 system system 250, 0 2021-11-14 21:15 rtc0
crw-r----- 1 root root 250, 1 2021-11-14 21:15 rtc1
在設(shè)備初始化代碼中增加修改rtc1用戶組:
index 766f404..0530a20 100755
--- a/rk3568/build/rootfs/init.rk3568.cfg
+++ b/rk3568/build/rootfs/init.rk3568.cfg
@@ -5,7 +5,8 @@
"jobs" : [{
"name" : "pre-init",
"cmds" : [
- "write /proc/sys/vm/min_free_kbytes 10240"
+ "write /proc/sys/vm/min_free_kbytes 10240",
+ "chown system system /dev/rtc1"
]
}, {
"name" : "init",
修改后查看rtc1用戶組:
# cd dev/# ls -al rtc*
lrwxrwxrwx 1 root system 4 2022-11-18 18:24 rtc -> rtc1
crw-r----- 1 system system 250, 0 2022-11-18 18:24 rtc0
crw-rw---- 1 system system 250, 1 2022-11-18 18:24 rtc1
用戶程序可正常打開:
11-18 18:00:36.159 533 533 E 01c02/TimeService: [time_service.cpp] set_rtc_time# RTC rtc_dev : /dev/rtc:11-18 18:00:36.161 533 533 E 01c02/TimeService: [time_service.cpp] set_rtc_time# RTC set_rtc_time success!!!!!!
驗(yàn)證結(jié)果:結(jié)果符合預(yù)期,連接網(wǎng)絡(luò)后系統(tǒng)時(shí)間,硬件時(shí)鐘均自動(dòng)同步為網(wǎng)絡(luò)時(shí)間。
//設(shè)置系統(tǒng)和硬件時(shí)間為非當(dāng)前時(shí)間。
# dateFri Jan 1 00:02:40 UTC 2021
# hwclockFri Jan 1 00:02:46 2021 0.000000 seconds//
連接網(wǎng)絡(luò)后,同步網(wǎng)絡(luò)時(shí)間,系統(tǒng)時(shí)間和硬件時(shí)鐘均自動(dòng)同步。
# dateMon Nov 21 15:19:28 UTC 2022
# hwclockMon Nov 21 15:19:32 2022 0.000000 seconds
總結(jié):
本文介紹了OpenHarmony中外置RTC調(diào)試和使用方法,以及RTC在操作系統(tǒng)中的作用,為后續(xù)NTP時(shí)間同步提供支持。
??想了解更多關(guān)于開源的內(nèi)容,請?jiān)L問:??
??51CTO 開源基礎(chǔ)軟件社區(qū)??
??https://ost.51cto.com??