Für die Echtzeituhr des Raspberry Pi 5 gibt es auf der Platine eine Anschlussbuchse, an die eine Batterie zur Stromversorgung angeschlossen werden kann.
Dies möchte ich natürlich mal ausprobieren.
Echtzeituhr
Jeder moderne Computer verfügt über eine Echtzeituhr (Real Time Clock = RTC). Dafür sitzt meist auf dem Mainboard eine Knopfzelle vom Typ CR2032, um sie ständig mit Strom zu versorgen.
Der Raspberry Pi hat erst mit der 5er Version eine RTC bekommen. Zuvor hat sich das Betriebssystem die aktuelle Zeit beim Start über das NTP (Network Time Protocol) aus dem Internet geholt.
Mein Amiga 500 bekam vor etwa 30 Jahren eine Echtzeituhr erst mit der Speichererweiterung auf 1MB dazu und ich möchte seitdem nicht mehr darauf verzichten.Bei der Softwareentwicklung ist sie unverzichtbar, da beispielsweise Build-Tools wie make auf eine aktuelle Zeit angewiesen sind.
Die verschiedenen Uhren von Raspberry Pi OS
Das Raspberry Pi OS besitzt verschiedene Uhren, um die aktuelle Zeit zu speichern.
System-Clock
Die System-Clock ist einfach nur eine Variable des OS, in dem die aktuelle Zeit steht, sie muss bei jedem Start des Raspberry Pi neu gesetzt werden.
Fake-HWClock
Die Fake-HWClock täuscht eine Hardware Echtzeituhr vor. Raspberry Pi OS speichert in der Datei /etc/fake-hwclock.data die aktuelle Zeit zwischen und liest sie dort beim Start wieder aus. Diese gibt es auch auf dem Raspberry Pi 4.
Echtzeituhr
Eine Echtzeituhr ist eine hardwareseitige Uhr, die die aktuelle Zeit hält und aktualisiert sich selbstständig, so lang Strom fließt. Sie erhält meistens durch eine Knopfzelle Strom, um die Zeit zu halten, wenn der Raspberry Pi abgeschaltet wird.
Die RTC des Raspberry Pi 5
Beim Raspberry Pi 5 ist die Echtzeituhr im Bereiches Spannungswandlers untergebracht. Zum Puffern der Uhr wird eine Knopfzelle vom Typ ML2020 an die JST Buchse (J5) links neben den HDMI-Buchsen angeschlossen. Die Knopfzelle ist wieder aufladbar und versorgt die Echtzeituhr auch dann mit Strom, wenn kein Netzteil angeschlossen ist.
Mit dem Kommando
timedatectl
kannst du dir anzeigen lassen, in welchem Zustand die RTC ist.
Du siehst hier: Die Echtzeituhr hat die Zeit 08:58, da die RTC die Zeit in UTC (Universal Time Coordinated) speichert. Erst das Betriebssystem macht mit Hilfe der eingestellten Zeitzone daraus die Local Time. Das Betriebssystem ist so konfiguriert, dass es beim Start die aktuelle Zeit über das Network Time Protocol (NTP) von einem Server aus dem Internet bezieht. Dies geschieht über den timesyncd
, dessen Ausgaben wir mit
sudo journalctl|grep timesyncd
im Logfile wieder finden.
Was passiert jetzt, wenn der Raspi in einer Umgebung ohne Internetverbindung hochfährt? Dazu habe ich mir ein weihnachtliches Experiment ausgedacht.
Das Experiment
Um die Arbeitsweise der RTC zu demonstrieren habe ich mir folgendes Experiment ausgedacht: Ein Programm, dass direkt nach dem Hochfahren von Raspberry Pi OS gestartet wird, schreibt zehn Logeinträge in ein Logfile in dem der WLAN Status ausgegeben wird.
Nachdem ich den Raspi in meinem Netzwerk mit der Zeit synchronisiert habe und die RTC gesetzt ist, bringe ich den Pi mit der angeschlossenen Batterie dort hin, wo das Internet am weitesten entfernt ist (zu meinen Eltern 🙂 und starte ihn dort. Dann lasse ich ihn über Nacht ohne die RTC Batterie dort und wiederhole das Ganze. Das Betriebssystem hat keine Möglichkeit, sich die aktuelle Zeit aus dem Netz zu laden, es ist also interessant, was dann passiert.
Der Programmcode sieht so aus:
#!/usr/bin/python
# encoding:utf-8
import logging
import io
import time
from os.path import exists
import subprocess
# liefert den nächsten Namen für die Logdatei
# im Format <basename>.<index>
def get_logname(basename):
for i in range(0,50):
filename = basename + '.' + str(i)
if not exists(filename):
return filename
return filename
logging.basicConfig( format='%(asctime)s [%(levelname)s] %(funcName)s: %(message)s',
filename=get_logname('/home/pi/git/rtcdemo/rtc.log'),
level=logging.DEBUG)
#Liest den Inhalt von /etc/fake-hwclock.data
def read_fake_clock():
with open('/etc/fake-hwclock.data') as f:
zeit = f.readline().strip('\n')
return zeit
def check_wlan():
# SSID der WLAN Verbindung auslesen
ssid = subprocess.check_output(['/usr/sbin/iwgetid', '--raw']).decode().strip()
if ssid:
return True
else:
return False
logging.debug('starting up...')
zeit = read_fake_clock()
logging.debug(f'Inhalt von /etc/fake-hwclock.data: {zeit}')
time.sleep(5)
try:
for i in range(0,10):
logging.debug(f'i={i} wlan={check_wlan()}')
except BaseException as e:
logging.error(f'Fehler aufgetreten: {e}')
Die Methode get_logname()
liefert mir jedes mal einen neuen Dateinamen, in dem sie so lang an den basename
einen Index anhängt, bis eine Datei dieses Namens nicht existiert. Um den Status des WLAN zu prüfen, wird das Shellkommando iwgetid
aufgerufen, wodurch wir die SSID des verbunden WLAN erhalten, wenn eine vorhanden ist, liefert check_wlan()
True
, sonst False
.
Das Programm findest du auch im Git-Repository.
Als nächstes konfiguriere ich den Raspi so, dass mein Programm per crond automatisch nach dem Neustart aufgerufen wird:
crontab -e
Die einzige Zeile, die ich eintrage, sieht wie folgt aus:
@reboot ~/git/rtcdemo/rtcdemo.py
Dies weist den crond an, bei jedem Neustart des Systems das Programm ~/git/rtcdemo/rtcdemo.py
zu starten.
Jetzt schalte ich den timesyncd ab
sudo systemctl disable timesyncd
Nach einem Neustart such ich im Logfile nach Verwendung der RTC:
sudo journalctl|grep rtc
Tatsächlich finde ich folgenden Eintrag:
Dec 22 09:28:43 uter kernel: rpi-rtc soc:rpi_rtc: setting system clock to 2023-12-22T08:28:39 UTC (1703233719)
Die System-Clock wurde mit der Zeit aus der Echtzeituhr gesetzt.
Experiment Tag 1
Erwartungshaltung: Da die Pufferbatterie die RTC mit Strom versorgt, wird die System-Clock beim Start mit der Zeit aus der Echtzeituhr synchronisiert. Daher sollte im Logfile tatsächlich die aktuelle Uhrzeit mit Datum 24.12. stehen.
Der Start des Raspberry Pi 5 geschah an Heiligabend um 20:50 Uhr.Kurz danach habe ich ihn mit dem Power-Taster wieder runter gefahren.
Experiment Tag 2
Erwartungshaltung: Das Betriebssystem hat jetzt weder die Möglichkeit, sich die aktuelle Zeit aus dem Netz zu holen noch liefert die Echtzeituhr einen Wert. Lediglich die Fake-HWClock bleibt als Quelle übrig. Diese müsste meinen Erwartungen nach, dass Datum vom Vortag haben.
Am 1. Weihnachtstag habe ich das Board um 12:41 gestartet.
Auswertung
Am Nachmittag des ersten Weihnachtsfeiertags habe ich den Raspi bei mir zu Hause wieder in Betrieb genommen. Im Dateisystem fand ich folgende Log-Dateien vor:
Drei Logdateien von drei Starts liegen im Verzeichnis:
- rtc.log.0 von Heiligabend 20:50 Uhr
- rtc.log.1 vom ersten Weihnachtstag um 12:41, das Dateidatum ist aber 24.12. 20:51 Uhr
- rtc.log.2 vom ersten Weihnachtstag um 14:43, das Dateidatum ist immer noch 24.12. 20:52 Uhr
Hier der Inhalt von rtc.log.0:
2023-12-24 20:50:50,182 [DEBUG] <module>: starting up...
2023-12-24 20:50:50,182 [DEBUG] <module>: Inhalt von /etc/fake-hwclock.data: 2023-12-24 19:50:39
2023-12-24 20:50:55,187 [ERROR] <module>: Fehler aufgetreten: Command '['/usr/sbin/iwgetid', '--raw']' returned non-zero exit status 255.
Du siehst, das Datum und die Zeit wurden aus der RTC gezogen, Der Aufruf von iwgetid
liefert einen Fehler, weil keine WLAN Verbindung bestand.
Jetzt zum Inhalt von rtc.log.1:
2023-12-24 20:51:25,365 [DEBUG] <module>: starting up...
2023-12-24 20:51:25,366 [DEBUG] <module>: Inhalt von /etc/fake-hwclock.data: 2023-12-24 19:51:15
2023-12-24 20:51:30,371 [ERROR] <module>: Fehler aufgetreten: Command '['/usr/sbin/iwgetid', '--raw']' returned non-zero exit status 255.
Mangels Alternativen stammt die Zeit von der Fake-HWClock, die beim Runterfahren an Heiligabend zuletzt aktualisiert wurde, daher ist für den Raspi immer noch Heiligabend.
Die rtc.log.2
stammt vom Neustart des Pis bei mir zu Hause.
2023-12-24 20:52:05,084 [DEBUG] <module>: starting up...
2023-12-24 20:52:05,085 [DEBUG] <module>: Inhalt von /etc/fake-hwclock.data: 2023-12-24 19:51:54
2023-12-24 20:52:10,089 [DEBUG] <module>: i=0 wlan=True
2023-12-24 20:52:10,090 [DEBUG] <module>: i=1 wlan=True
2023-12-24 20:52:10,091 [DEBUG] <module>: i=2 wlan=True
2023-12-24 20:52:10,092 [DEBUG] <module>: i=3 wlan=True
2023-12-24 20:52:10,093 [DEBUG] <module>: i=4 wlan=True
2023-12-24 20:52:10,093 [DEBUG] <module>: i=5 wlan=True
2023-12-24 20:52:10,094 [DEBUG] <module>: i=6 wlan=True
2023-12-24 20:52:10,095 [DEBUG] <module>: i=7 wlan=True
2023-12-24 20:52:10,096 [DEBUG] <module>: i=8 wlan=True
2023-12-24 20:52:10,096 [DEBUG] <module>: i=9 wlan=True
Hier ist immer noch Heiligabend, da der timesyncd noch abgeschaltet ist. Also schalte ich ihn wieder ein
sudo systemctl enable timesyncd
Fazit
Die Echtzeituhr ist eine gute Zeitquelle für Projekte, bei denen es auf die aktuelle Zeit ankommt, aber keine Verbindung zu einem NTP Server gewährleistet ist. Die Pufferbatterie ist derzeit für weniger als 6 Euro zu haben. Allerdings macht mir die verbaute JST Buchse nicht gerade den stabilsten Eindruck und der Stecker bietet für die beiden dünnen Kabel keine Zugentlastung.
Ein Tipp noch: Falls du den Active Cooler benutzen solltest, ist es sinnvoller, erst die Batterie einzustecken und danach den Cooler aufzusetzen. Umgekehrt wird das durch die räumliche Enge zum Kühlkörper eine ziemliche Fummelei.
Update 20.06.24 10:04: Wie du eine Echtzeituhr am Raspberry Pi 4 nachrüsten kannst, zeige ich dir hier.