Zegar czasu rzeczywistego w OpenWrt
Ostatnia zmiana: 2015-07-01 07:51

Zwykłe routery pozbawione są pewnego elementu spotykanego w normalnym komputerze - zegarze czasu rzeczywistego, zwanego w skrócie RTC. Firmware na routerze radzą sobie w różny sposób aby ustawić czas - albo zapisują w plikach bieżący albo synchronizują czas w serwerami w internecie. Jednakże często czas jest potrzeby już w momencie startu routera np. do poprawnego zestawienia tunelu VPN i uzgodnienia ważności certyfikatów.
Lukę w funkcjonalności routera można uzupełnić dodając proste moduły RTC dedykowane np. do Arduino, pracujące na magistrali I2C. Ponieważ mało który router posiada taką magistralę - można ją zrobić wykorzystując dwa wolne gpio lub zastosować inny moduł na usb.



W tym poradniku wykorzystano moduł oparty na chipie DS3231, choć można użyć popularnego DS1307.
UWAGA: niektóre moduły mogą do działania wymagać napięcia 5V i nie mogą pracować przy napięciu 3.3V jakim posługuje się router.

Magistrala I2C

Poniżej przedstawiono dwa sposoby utworzenia magistrali I2C - z wykorzystaniem wolnych linii GPIO lub gotowego modułu na USB. Niektóre routery mają już wbudowaną magistralę (Alix, jjPlus) i można także z niej skorzystać.

GPIO

Wykorzystujemy wspomniany już poradnik:


    # opkg update
    # opkg install kmod-i2c-gpio-custom
    # insmod i2c-gpio-custom bus0=0,8,7

Gdzie:

  • 0 - numer magistrali
  • 8 - numer gpio linii danych - SDA
  • 7 - numer gpio linii zegara - SCL
Do podłączenia wykorzystano dwa wolne gpio o numerach 7 i 8. Zakładamy że moduł jest podłączony odpowiednio do routera:


    Piny modułu - podłączenie do routera
    VCC - zasilanie 3.3V
    SDA - linia gpio 8
    SCL - linia gpio 7
    GND - masa 

USB

W tym przypadku wykorzystujemy gotowy moduł oparty np. na projekcie i2c-tiny-usb i instalujemy odpowiednie sterowniki:


    # opkg update
    # opkg install kmod-i2c-tiny-usb

Moduł podłączamy do i2c-tiny-usb w następujący sposób


    Piny modułu - piny i2c-tiny-usb
    VCC - zasilanie 3.3V 
    SDA - SDA
    SCL - SCL
    GND - masa

Instalacja modułów zegara



    # opkg install kmod-rtc-ds1307

Tego pakietu nie ma standardowo dla niektórych platform (np. ar71xx). Jeżeli ktoś używa moich obrazów to jest on dostępny w moim repozytorium, jeżeli nie - trzeba samemu skompilować kernel z odpowiednimi opcjami.


    # insmod rtc-ds1307
    # echo ds1307 0x68 > /sys/bus/i2c/devices/i2c-0/new_device

Ostatnie linia odpowiada na "wykrycie" urządzenia na magistrali, co powinno objawić się wpisami w logu (logread):


    Fri Jan 23 19:04:53 2015 kern.info kernel: [  156.820000] rtc-ds1307 0-0068: rtc core: registered ds1307 as rtc0
    Fri Jan 23 19:04:53 2015 kern.info kernel: [  156.820000] rtc-ds1307 0-0068: 56 bytes nvram
    Fri Jan 23 19:04:53 2015 kern.info kernel: [  156.830000] i2c i2c-0: new_device: Instantiated device ds1307 at 0x68

Ustawienie czasu



    # hwclock -s

Powoduje to odczytanie i ustawienie aktualnego czasu w systemie.

Zapisane czasu do rtc

Przy pierwszym uruchomieniu stan zegara może być niewłaściwy (np. może mieć ustawiony rok 1970). Należy wtedy zapisać do układu bieżący czas poleceniem:


    # hwclock -w

Aby sprawdzić czas zapisany w układzie wykonujemy:


    # hwclock -r

Diagnostyka

Po załadowaniu modułów powinno pojawić się urządzenie /dev/rtc0


    # ls -al /dev/rtc0
    cw-r--r--    1 root     root      254,   0 Jan 23 19:03 /dev/rtc0

W /sys powinno też pojawić się nowe urządzenie z którego możemy bezpośrednio odczytać datę i czas:


    # cd /sys/bus/i2c/devices/i2c-0/0-0068/rtc/rtc0
    # ls -al
    date dev device hctosys max_user_freq name since_epoch subsystem time uevent
    # cat date 
    2015-01-23
    # cat time 
    19:04:20
    # cat name 
    ds1307

Automatyzacja

Ładowanie modułu do magistrali można dodać np. do pliku /etc/modules.d/rtc-ds1307. Wykrywanie zaś urządzenia i odczyt czasu np w /etc/init.d/sysfixtime.