Die Echtzeituhr des Raspberry Pi 5

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.

Inhalt der /etc/fake-hwclock.data Datei 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

Die offizielle Pufferbatterie für die Echtzeituhr des Raspberry Pi 5
Die offizielle Pufferbatterie für die Echtzeituhr 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.

Ausgabe von timedatectl auf dem Raspberry Pi 5
Ausgabe von timedatectl auf dem Raspberry Pi 5

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.

Ausgaben des timesyncd im Logfile

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 Indes 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.

Raspberry Pi 5 im Weihnachtsbaum
Raspberry Pi 5 im Weihnachtsbaum

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:

Es liegen drei Logdateien im Verzeichnis

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.

Schreibe einen Kommentar

Cookie Consent Banner von Real Cookie Banner