嵌入式開發中,幾個時間概念?
我生待明日,萬事成蹉跎。—— 明 · 錢福《明日歌》
1 前言
在嵌入式系統中 (包括大部分電子設備:手機、平板、手環、手錶等等),時間的概念非常重要。如打印 log 時的時間戳、定時關機、心跳上報、日曆功能、鬧鐘等等。上述這些功能都需要一個相對精確的時間系統。
經常涉及的與時間相關的術語包括:硬件時鐘、系統時鐘、網絡時鐘、時區修改和同步。日常生活和工作中可能接觸到的時區概念包括:UTC
、GMT
、CST
、DST
。在網絡時間中可能接觸到的概念又有:NTP
、SNTP
、NITZ
。本文將會對上述涉及到的概念進行系統的整理和探討。
2 瞭解概念
下面對幾個概念進行集中陳述。
2.1 時區
時區 [1] 是指地球上的不同區域使用同一個時間定義。以前,人們通過觀察太陽的位置(時角)決定時間,這就使得不同經度的地方的時間有所不同(地方時)。1863 年,首次使用時區的概念。通過設立一個區域的標準時間部分地解決了這個問題。
時區劃分規則: 將全球按經線從東到西劃分爲 24 個時區,其中東、西各 12 個時區,每個時區跨越經度 15°,0 區和 12 區跨越東西各 7.5°。規定相鄰區域的時間相差 1 小時,這樣 24 個時區剛好是 24 小時,地球自轉一圈。如下圖是全球時區的劃分明細。常見的時區概念包括:GMT
、UTC
、CST
、DST
。
-
GMT(Greenwich Mean Time) 指格林尼治標準時間,它是第一個世界時。
GMT 12:00
就是指格林尼治天文臺當地的正午 12:00,而 GMT+8 12:00,則是指東八區的北京當地時間的 12:00。格林尼治標準時間的正午是指當太陽橫穿格林尼治子午線時(也就是在格林尼治時)的時間。由於地球在它的橢圓軌道里的運動速度不均勻,這個時刻可能和實際的太陽時相差 16 分鐘。 -
UTC(Coordinated Universal Time)是指協調世界時,又稱世界標準時間。它是以原子時爲基礎,由於現在世界上最精確的原子鐘 50 億年纔會誤差 1 秒,所以 UTC 時間標準非常精確。每隔幾年協調世界時組織都會給世界時 + 1 秒,讓基於原子鐘的世界時和基於天文學(人類感知)的格林尼治標準時間 (GMT) 相差不至於太大。UTC 是現在世界使用的標準時間,UTC 與 GMT 時間基本相同。
-
CST(China Standard Time) 指中國標準時間。
GMT + 8 = UTC + 8 = CST
。 -
DST(Daylight Saving Time) 夏令時,又稱:“日光節約時制”。是一種爲節約能源而人爲規定地方時間的制度,在這一制度實行期間所採用的統一時間稱爲 “夏令時間”。一般在天亮早的夏季人爲將時間調快一小時,可以使人早起早睡,減少照明量,以充分利用光照資源,從而節約照明用電。各個採納夏時制的國傢俱體規定不同。全世界有近 110 個國家每年要實行夏令時。中國現在已經不再使用夏令時。
2.2 時鐘
常見的幾個時鐘概念包括:硬件時鐘、系統時鐘、網絡時鐘。
- 硬件時鐘。在嵌入式領域也就是 RTC 時鐘 (Real Time Clock)。大多采用精度較高的晶振作爲時鐘源。在主電源掉電時,還可以工作,需要外加電池供電。通常把集成於芯片內部的 RTC 稱爲片內 RTC,在芯片外擴展的 RTC 稱爲外部 RTC。
-
系統時鐘。指軟件系統的時鐘。在
linux
和一些rtos
中,啓動時會去讀取硬件時鐘 (RTC),之後則獨立運行。獨立運行的好處對於普通用戶意義不大,但對於linux
網絡管理員卻有很大的用處。例如,要將一個很大的網絡中 (跨越若干時區) 的服務器同步,假如位於美國紐約的linux
服務器和北京的 Linux 服務器,其中一臺服務器無須改變硬件時鐘而只需臨時設置一個系統時間,如要將北京服務器上的系統時間設置爲紐約時間,兩臺服務器完成文件的同步後,再與原來的硬件時鐘同步一下即可。這樣系統時鐘和硬件時鐘就提供了更爲靈活的操作。 -
網絡時鐘。網絡時鐘的時間源來自於專業授時的服務器 (SNTP、NTP)。實現方案是在網絡上指定若干時鐘源服務器,爲用戶提供授時服務,並且這些服務器之間能夠相互比較校正,以提高準確度。在移動蜂窩網絡中,基站也可以通過無線網絡向移動設備提供本地日期和時間、時區、夏時制偏移。網絡時鐘的精度一般都很高,可以達到毫秒級,可以用來對嵌入式設備進行時間同步。
2.3 時間同步
時間同步對嵌入式設備很重要,一些功能業務甚至依賴於時間信息來完成。如自注冊 DM 業務,需要週期性的向運營商服務器上報信息,這些信息上報都是以天或者是月爲週期,不可能靠軟件timer
來實現。和此類似的功能都需要以標準時間爲基準,以此完成條件的觸發。下面來探討時間同步的話題。
2.3.1 SNTP
SNTP 是簡單網絡時間協議 (Simple Network Time protocol) 的簡稱,它是目前Internet
網上實現時間同步的一種重要工程化方法。SNTP
由NTP
改編而來,SNTP
其實是NTP
的子集,只是NTP
可以 分發和授時,而SNTP
只有授時沒有分發,也就是說你只能從SNTP
獲取時間,其他的什麼都做不了,SNTP
簡化了NTP
的全部流程,這樣節約成本,但只能同步一個時間源。SNTP
協議採用客戶端 / 服務器的工作方式。SNTP
服務器通過接收GPS
信號或自帶的原子鐘作爲系統的時間基準。SNTP
客戶端 (嵌入式設備) 能夠通過定期訪問SNTP
服務器獲得準確的時間信息,用於調整客戶端自身所在系統的時間,達到同步時間的目的。在linux
系統中一般有現成的 SNTP 客戶端可以安裝使用,在其他的嵌入式平臺上需要移植或自主開發。一些可用的 SNTP 服務器彙總如下 (親測可以 ping 通):
-
國家授時中心 NTP 服務器:ntp.ntsc.ac.cn
-
阿里雲公共 NTP 服務器:time.pool.aliyun.com
-
騰訊雲公共 NTP 服務器:time1.cloud.tencent.com
-
教育網(高校自建)服務器:ntp.sjtu.edu.cn
2.3.2 NITZ
NITZ(Network Identity and Time Zone)是一種通過無線網絡向移動設備提供本地日期和時間、時區、夏時制偏移,以及網絡提供商身份信息的機制,這通常用於無線蜂窩網絡設備 (手機、通信模組) 的自動更新系統時間。對於其他網絡時間協議,NITZ 的質量和執行力度都相對較弱。有些運營商根本就不支持,例如在國內,本地測試 (廣東) 發現,中國移動和中國電信是支持NITZ
的,中國聯通就根本不支持。再者,與SNTP
相比,SNTP
授時能使時間分辨率達到毫秒級,NITZ
則 “對於時間只能精確到數分鐘”。但NITZ
不用連上互聯網,能駐上無線蜂窩網絡就行,而SNTP
必須連接互聯網。
3 應用
3.1 linux 中時間命令
linux 命令中的date
命令是用來設置和查詢系統時間的,而hwclock
命令是用來設置和讀寫RTC
時間 (硬件時間)。有一點需要注意,linux
的時間系統是由「新紀元時間」Epoch 開始計算起,單位爲秒,Epoch 則是指定爲 1970 年 1 月 1 日 0 點 0 分 0 秒,格林威治時間 (GMT)。date +%s
命令可以讀取從 1970 年 1 月 1 日 0 點 0 分 0 秒開始到當前的秒數。
- 讀取當前秒數 (以 1970 年 1 月 1 日 0 點 0 分 0 秒爲計算起點);
book@zhang.c:~$ date +%s
1653752545
- 讀系統時間:
date
;
book@zhang.c:~$ date
Sat May 28 22:41:26 CST 2022
- 設置系統時間:
date -s "20220501 12:00:00"
,date -s
命令設置時間只會影響系統時間,不會設置 RTC 時間,如果需要把當前系統時間同步設置到 RTC 中,需要額外調用hwclock
命令;
book@zhang.c:~$ date -s "20220501 12:00:00"
Sun May 1 12:00:00 CST 2022
- 有關
rtc
時間的操作,主要是hwclock
命令使用;
#讀取並打印當前的rtc時間
hwclock -r
#讀取RTC時間並設置到系統時間中去
hwclock -s
#把當前的系統時間設置到RTC中
hwclock -w
#完整的設置RTC的時間可執行如下命令
date -s "20220501 12:00:00"
hwclock -w
date
命令格式化的顯示時間,可以看如下的Command
這一列。
Format/result | Command | Output
--------------------------------+----------------------------+------------------------------
YYYY-MM-DD | date -I | $(date -I)
YYYY-MM-DD_hh:mm:ss | date +%F_%T | $(date +%F_%T)
YYYYMMDD_hhmmss | date +%Y%m%d_%H%M%S | $(date +%Y%m%d_%H%M%S)
YYYYMMDD_hhmmss (UTC version) | date --utc +%Y%m%d_%H%M%SZ | $(date --utc +%Y%m%d_%H%M%SZ)
YYYYMMDD_hhmmss (with local TZ) | date +%Y%m%d_%H%M%S%Z | $(date +%Y%m%d_%H%M%S%Z)
YYYYMMSShhmmss | date +%Y%m%d%H%M%S | $(date +%Y%m%d%H%M%S)
YYYYMMSShhmmssnnnnnnnnn | date +%Y%m%d%H%M%S%N | $(date +%Y%m%d%H%M%S%N)
YYMMDD_hhmmss | date +%y%m%d_%H%M%S | $(date +%y%m%d_%H%M%S)
Seconds since UNIX epoch: | date +%s | $(date +%s)
Nanoseconds only: | date +%N | $(date +%N)
Nanoseconds since UNIX epoch: | date +%s%N | $(date +%s%N)
ISO8601 UTC timestamp | date --utc +%FT%TZ | $(date --utc +%FT%TZ)
ISO8601 UTC timestamp + ms | date --utc +%FT%T.%3NZ | $(date --utc +%FT%T.%3NZ)
ISO8601 Local TZ timestamp | date +%FT%T%Z | $(date +%FT%T%Z)
YYYY-MM-DD (Short day) | date +%F\(%a\) | $(date +%F\(%a\))
YYYY-MM-DD (Long day) | date +%F\(%A\) | $(date +%F\(%A\))
3.2 SNTP 和 NITZ
在手機 (包括 Android 和功能機) 和模組產品中,SNTP
和NITZ
兩種同步系統時間的策略一般都會用到。默認使用的是 NITZ 來獲取網絡時間,但是需要有運營商的支持才能使用 (中國聯通就不支持),而有些設備產品只支持 WIFI 等無線網絡,而不支持移動網絡,此時就需要採用SNTP
方式來獲取網絡時間進行同步了。SNTP
協議時間戳是以 1900 年 1 月 1 日 0 點 0 分 0 秒爲起點,而linux
時間戳從 1970 年 1 月 1 日 0 點 0 分 0 秒開始記秒數,即記錄到SNTP
結構體中的時間包含了 JAN_1970(從 1900 到 1970 共 70 年的秒數)。在拿到SNTP
時間後,往 linux 同步時間時,需要減掉 JAN_1970。
4 總結
-
UTC
與GMT
時間基本相同; -
硬件時鐘和系統時鐘同步後,會分開獨立運行;
-
網絡時鐘的精度都比較高,可以用
SNTP
或NITZ
來進行同步,尤其SNTP
時間同步精度可以達到毫秒級。 -
linux
系統的計時起點爲 1970 年 1 月 1 日 0 點 0 分 0 秒,其他嵌入式系統在做網絡時間同步時,也一定要確認好計時起點。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Rm9w7TxhTDGAtFKnokjaMA