樹莓派:光陰的故事

做者:Vamei 出處:http://www.cnblogs.com/vamei 嚴禁任何形式轉載。html

 

對於電子設備來講,時間都是基礎性的功能,也很容易被人忽視。上世紀的「千年蟲」問題,就是時間方面設計缺陷形成的。對於網絡鏈接的多設備來講,保持時間同步又是一個新的問題。對於樹莓派的衆多應用情景來講,時間的準確性都相當重要。python

 

NTP服務

樹莓派中內置了NTP服務,因此連上網以後就能夠自動調整時間。NTP是網絡時間協議(Network Time Protocol)的簡稱,主要用於網絡時間的同步。NTP協議早在80年代就已經誕生,至今仍是互聯網的基礎性協議之一。NTP通訊分爲服務器和客戶端兩方。客戶端發出的數據包中,包含有發出時客戶端的時間。服務器收到數據包並回復。回覆的數據包中,附加了服務器收到和發出數據包的時間。客戶端收到回覆後,就能夠得到網絡延遲時間,以及本身和服務器的時間差。客戶端據此調整本身的時鐘,就能夠與服務器時間保持同步。bash

NTU客戶與服務器服務器

 

你能夠經過下面命令來查詢當前使用的NTP服務器:網絡

sudo ntpq -pn

 命令返回:ide

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 203.135.184.123 .GPS.            1 u  322   64   20  365.136   -7.571  15.792
 223.112.179.133 .INIT.          16 u    - 1024    0    0.000    0.000   0.000
*202.112.29.82   202.118.1.46     2 u  122   64  276   53.148    0.766   0.868

行首加*號的是當前服務器。此外,還列出了網絡延遲時間(delay)、與服務器時間差(offset)等關鍵的NTP時間數據。單位是milliseconds。工具

 

若是NTP服務出現問題,形成樹莓派時間錯誤,能夠強制要求NTP對錶: ui

sudo service ntp stop
sudo ntpd -gq
sudo service ntp start

上面的第一句和第三句分別用於中止和啓動NTP服務。 this

 

不使用NTP,你也能夠手動調整系統時間: spa

sudo date -s "1 Jan 2017 00:00:00"

即把系統時間調整爲2017年1月1日00:00:00。

  

而後用date命令來顯示系統當前時間:

date

 

時區設置

地球自西向東轉到。因此,全球不一樣經度地點的日出日落以及正午的時間不一樣。人們又習慣於用一樣的12點來表明正午,這意味着不一樣經度的人要用不同的表。但是,若是人每時每刻都要根據經度調錶,就會很是麻煩。所以,地球以15度的經度來劃分時區,一個時區內的表用統一的時間,向東跨過一個時區,就須要把表調快1小時。固然,時區的劃分不是嚴格的按照15度。好比說,一些地跨多個時區的國家有可能用統一一個時區,例如中國。下面是地球上時區分佈的地圖。

 

對於不一樣地區的用戶來講,每每須要把樹莓派調整成當地的時區。你能夠用raspi-config進入到樹莓派的設置頁面,在"4 Localisation Options"->"I2 Change Timezone"中修改時區。

固然,你也能夠用下面的命令手動修改:

sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

注意到,/user/share/zoneinfo中有多個以各大洲名字命令的文件夾,裏面的文件以該州的主要城市命名。把對應城市的文件複製到/etc/localtime,就能夠把系統的時區設成該城市所用的時區。這裏我把時區修改成"Shanghai",也就是上海。修改以後,用date命令查看時間,能夠看到時區簡寫變成CST,也就是「上海時間」的縮寫:

Tue  3 Jan 20:42:24 CST 2017

 

用date命令查看UTC時間:

date -u

顯示的時間正好相差8個小時:

Tue  3 Jan 12:42:24 UTC 2017

 

實時時鐘

大多數電腦在主板上包含了一個實時時鐘(RTC,Real Time Clock)。實時時鐘是一個有電源的表,能在電腦斷電時繼續計時。所以,電腦斷電後一天再開機,你會發現電腦的時鐘也往前走了一天。但樹莓派並不包含一個實時時鐘。所以,若是樹莓派斷電一天再開機,在NTP服務校訂時間以前,你會發現樹莓派的時間還停留在一天前。爲了克服這一問題,你能夠給樹莓派附加一個實時時鐘,好比PiFace專門爲樹莓派設計的實時時鐘。

這個實時時鐘設計成一個使用鈕釦電池的電路板。把PiFace電路板的孔對準樹莓派的GPIO針腳插入,就可使用了。插入位置以下圖所示。插入正確的狀況下,電池正好在樹莓派CPU的上方。網上也有人詬病這一設計,認爲電池的發熱會影響樹莓派CPU的散熱。不過我在使用中並無太大問題。

爲了使用這款實時時鐘,我還須要進行一些設置。首先,這塊電路板是經過I2C接口與樹莓派通訊的,因此要在raspi-config的頁面中打開I2C接口。而後,安裝所需的工具包: 

sudo apt-get install i2c-tools
sudo apt-get install python-smbus

 

接下來,賦予用戶pi使用I2C接口的權限:

sudo usermod -aG i2c pi

 

打開文件/etc/modules,這裏面列出了系統能夠加載的模塊。檢查是否有以下兩行。若是沒有的話請添加:

i2c-dev
i2c-bcm2708

 

下面一段程序修改自官網程序,用來讓樹莓派在開機時自動加載實時時鐘。把下面程序保存爲rtc.bash,並運行:

#!/bin/bash #======================================================================= # NAME: set_revision_var # DESCRIPTION: Stores the revision number of this Raspberry Pi into # $RPI_REVISION #======================================================================= set_revision_var() { revision=$(grep "Revision" /proc/cpuinfo | sed -e "s/Revision\t: //") RPI2_REVISION=$((16#a01041)) RPI3_REVISION=$((16#a02082)) if [ "$((16#$revision))" -ge "$RPI3_REVISION" ]; then RPI_REVISION="3"
    elif [ "$((16#$revision))" -ge "$RPI2_REVISION" ]; then RPI_REVISION="2"
    else RPI_REVISION="1"
    fi } #======================================================================= # NAME: start_on_boot # DESCRIPTION: Load the I2C modules and send magic number to RTC, on boot. #======================================================================= start_on_boot() { echo "[info]Create a new pifacertc init script to load time from PiFace RTC."
    echo "[info]Adding /etc/init.d/pifacertc ."

    if [[ $RPI_REVISION == "3" ]]; then i=1  # i2c-1
    elif [[ $RPI_REVISION == "2" ]]; then i=1  # i2c-1
    else i=0  # i2c-0
    fi

    cat > /etc/init.d/pifacertc  << EOF #!/bin/sh ### BEGIN INIT INFO # Provides: pifacertc # Required-Start:    udev mountkernfs \$remote_fs raspi-config # Required-Stop: # Default-Start: S # Default-Stop: # Short-Description: Add the PiFace RTC # Description: Add the PiFace RTC ### END INIT INFO . /lib/lsb/init-functions case "\$1" in start) log_success_msg "Probe the i2c-dev"
    modprobe i2c-dev # Calibrate the clock (default: 0x47). See datasheet for MCP7940N log_success_msg "Calibrate the clock" i2cset -y $i 0x6f 0x08 0x47 log_success_msg "Probe the mcp7941x driver"
    modprobe i2c:mcp7941x log_success_msg "Add the mcp7941x device in the sys filesystem" # https://www.kernel.org/doc/Documentation/i2c/instantiating-devices
    echo mcp7941x 0x6f > /sys/class/i2c-dev/i2c-$i/device/new_device log_success_msg "Synchronise the system clock and hardware RTC" hwclock --hctosys ;; stop) ;; restart) ;; force-reload) ;; *) echo "Usage: \$0 start" >&2 exit 3 ;; esac EOF chmod +x /etc/init.d/pifacertc echo "[info]Install the pifacertc init script" update-rc.d pifacertc defaults } set_revision_var && start_on_boot

 

完成後重啓電腦。此時樹莓派應該已經自動經過I2C接口加載了實時時鐘。你能夠經過下面命令來檢查實時時鐘是否就位:

sudo i2cdetect -y 1

若是就位,那麼60開頭的行會有一個"UU"的標準位。你能夠經過下面的命令,讀出實時時鐘的時間:

sudo hwclock -r 

你能夠經過下面的命令,把當前系統時間寫入實時時鐘:

sudo hwclock --systohc

 

有了實時時鐘,你就能夠在無網環境下保持時間的連續性。PiFace的產品賣得有一些貴。淘寶上還有一些便宜的實時時鐘能夠選購。另外,PiFace官網速度很慢。須要說明書的,能夠在這裏下載 

 

date用例

文章中多處使用了date命令。date是UNIX系統下經常使用的時間命令工具,能提供很是豐富的時間功能,好比以特定格式顯示時間:

date +"%Y year %m month %d day"

+號後面的字符串表明了時間顯示格式。%開頭的標識符會用時間信息填充。%Y表明了年,%m表明了month,%d表明了日期。因此上面命令返回:

2017 year 01 month 01 day

更多的標識符能夠經過man date來查詢文檔。

 

date不必定只顯示當前時間,它還能夠用來顯示一個用戶輸入的時間:

date --date="2017/01/03 12:00:00"

這個功能看起來有些雞肋,但實際上能夠用於時間推算。好比說下面的命令就能夠用於推算2016年11月12日以前1個月的時間:

date --date="2016/11/12 -1 month"

除了"-1 month",還能夠是"+1 second"、"-2 day"等多種時間差,能知足各類各樣的時間推算需求。

 

date的功能極爲豐富,這裏只列出了一些常見用例。其餘使用能夠參考man date的文檔。

 

總結

樹莓派提供了NTP服務,經過網絡來校訂時間。即便在斷網狀況下,也能夠物理計時實施來校訂時間。而樹莓派使用的Linux系統,也提供了date這樣便利的時間工具。

 

歡迎閱讀「騎着企鵝採樹莓」系列文章 

相關文章
相關標籤/搜索