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:
- 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
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:
Aby sprawdzić czas zapisany w układzie wykonujemy:
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.