RasPi zeitgesteuert starten per RTC

Auf Dauerbetrieb

Der Dauerbetrieb erfordert noch ein paar Arbeiten an der Konfiguration, um die manuell vorgenommenen Aktionen zu automatisieren. Deaktivieren Sie dazu in der Datei /etc/modprobe.d/raspi-blacklist.conf den Eintrag blacklist i2c-bcm2708, und tragen Sie stattdessen entweder in der Datei /etc/modprobe.d/raspi.conf die Zeile options i2c-bcm2708 baudrate=400000 oder in /etc/modules die Zeile i2c-dev ein.

Mit sudo update-rc.d fake-hwclock remove und sudo update-rc.d hwclock remove bereinigen Sie die Startskripte. Dann wenden Sie im Verzeichnis /etc/init.d den Patch aus Listing 5 mit dem folgenden Kommando auf das entsprechende Skript an:

$ patch < hwclock.sh.patch

Listing 5

 

--- hwclock.sh.original 2012-12-22 06:57:47.000000000 +0100
+++ hwclock.sh  2013-11-03 19:27:50.653988109 +0100
@@ -21,10 +21,10 @@
 ### BEGIN INIT INFO
 # Provides:          hwclock
-# Required-Start:    mountdevsubfs
+# Required-Start:    kmod
 # Required-Stop:     $local_fs
 # Default-Start:     S
-# X-Start-Before:    checkroot
+# X-Start-Before:
 # Default-Stop:      0 6
 ### END INIT INFO
@@ -33,6 +33,7 @@
 HWCLOCKACCESS=yes
 HWCLOCKPARS=
 HCTOSYS_DEVICE=rtc0
+I2CBUS=0
 # We only want to use the system timezone or else we'll get
 # potential inconsistency at startup.
@@ -43,6 +44,7 @@
     [ ! -x /sbin/hwclock ] && return 0
     [ ! -r /etc/default/rcS ] || . /etc/default/rcS
     [ ! -r /etc/default/hwclock ] || . /etc/default/hwclock
+    [ ! -r /etc/default/rtc ] || . /etc/default/rtc
     . /lib/lsb/init-functions
     verbose_log_action_msg() { [ "$VERBOSE" = no ] || log_action_msg "$@"; }
@@ -61,8 +63,8 @@
                printf "0.0 0 0.0\n0\nUTC" > /etc/adjtime
            fi
-           if [ -d /run/udev ] || [ -d /dev/.udev ]; then
-               return 0
+           if [ ! -c /dev/HCTOSYS_DEVICE ]; then
+               echo mcp7941x 0x6f > /sys/bus/i2c/devices/i2c-$I2CBUS/new_device
            fi
            if [ "$HWCLOCKACCESS" != no ]; then

Außerdem fügen Sie das neue Startskript aus Listing 6 hinzu. Beide Startskripte lesen aus der Datei in Listing 7 den zu verwendenden I2C-Bus.

Listing 6

 

#!/bin/sh
### BEGIN INIT INFO
# Provides:          raspi-rtc-power
# Required-Start:    kmod
# Required-Stop:     halt
# X-Stop-After:      networking
# Default-Start:     S
# Default-Stop:      0
# Short-Description: on/off Raspi-RTC-Power
# Description:       switching on/off power via RTC chip on Raspi extension board
### END INIT INFO
set -e
. /lib/lsb/init-functions
ALARM=0;
I2CBUS=0;
if [ -r /etc/default/rtc ]; then
  . /etc/default/rtc
fi
if [ -r /etc/wakealarm ]; then
  ALARM=$(cat /etc/wakealarm)
fi
case "${1:-}" in
  start)
    log_action_begin_msg "Switching on RasPi-RTC-Power "
    modprobe i2c-dev
    i2cset -f -y $I2CBUS 0x6f 0x07 0x00
    ES=$?
    log_action_end_msg $ES
    ;;
  stop)
    log_action_begin_msg "Switching off RasPi-RTC-Power "
    /sbin/rtc-power $I2CBUS $ALARM
    ES=$?
    log_action_end_msg $ES
    ;;
  *)
    echo "Usage: ${0:-} {start|stop}" >&2
    exit 1
    ;;
esac

Listing 7

 

# Default settings for Raspi-RTC-Power. This file is
# sourced by /bin/sh from /etc/init.d/raspi-rtc-power.
# Number of I2C bus hosting the RTC chip: 0 or 1
I2CBUS=bus#

Die nunmehr aktualisierten Startskripte übernehmen Sie mit den folgenden zwei Kommandos wieder in den Systembetrieb:

$ sudo update-rc.d hwclock defaults
$ sudo update-rc.d raspi-rtc-power defaults

Wie erwähnt stehen im aktuellen Treiber für den MCP79410 nicht alle notwendigen Funktionen bereit. Daher braucht es noch ein eigenes Programm (siehe Listing 8), um beim Systemstopp sowohl die Weckzeit zu programmieren als auch das Control-Register so zu setzen, dass die Verzögerungszeit des Zeitgebers abläuft [5].

Setzen Sie die Weckzeit auf 0, weckt der Chip den RasPi nicht auf. Das klappt dann nur manuell oder durch Wiederkehr der Stromversorgung. Liegt die Weckzeit aber mindestens 120 Sekunden in der Zukunft, dann gilt diese, ansonsten gilt der Zeitpunkt in genau 120 Sekunden von jetzt als Weckzeit.

Das Listing 8 speichern Sie in der Datei rtc-power.c und übersetzen diese mit gcc rtc-power.c -o rtc-power gleich am RasPi selbst. Bevor Sie rtc-power ins Verzeichnis /sbin/ verschieben, setzen Sie noch den Eigentümer und die Gruppe mit sudo chown root:root rtc-power auf die passenden Werte.

Listing 8

 

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <time.h>
#define MCP7941X        0x6f
#define CTRLREG         0x07
#define ALARM0REG       0x0a
#define ALARMREGSETLEN  6
#define ALARMMC         0x70
#define RTCOUT1         0x80
#define ALARM0EN        0x10
#define MINTIMEGAP      120
char int2bcd(char val) {
  return (val%10+16*(val/10));
}
int main(int argc, char *argv[])
{
  int file;
  int i2cbus; // I2C bus number
  char i2cdevicename[11];
  char cbuffer[2]; // I2C Control Buffer
  char buffer[ALARMREGSETLEN+1]; // I2C Alarm0 Buffer
  char *end;
  time_t atime; // Alarm time in seconds since epoch
  time_t now = time(NULL);
  struct tm *alarm; // Alarm in broken down time
  /* get command line parameters */
  if (argc != 3) {
    printf("Error: 2 Parameters expected.\n");
    exit(1);
  }
  i2cbus = strtol(argv[1], &end, 0);
  if (*end || i2cbus < 0 || i2cbus > 1) {
    printf("Error: I2C Bus Number 0 or 1 expected.\n");
    exit(2);
  }
  atime = strtol(argv[2], &end, 0);
  if (*end || atime < 0) {
    printf("Error: Alarm time zero or greater expected.\n");
    exit(3);
  }
  /* set RTC control and ALARM0 accordingly */
  if (atime == 0) { // in case alarm time is zero then ...
    int i;
    cbuffer[1] = RTCOUT1; // ... simply switch off ...
    for (i=1; i<=ALARMREGSETLEN; i++) buffer[i]=0; // ... and clear alarm time
  }
  else { // in case of a non-zero alarm time ....
    cbuffer[1] = ALARM0EN; // ... enable the alarm ...
    if (atime - now < MINTIMEGAP) atime = now + MINTIMEGAP; // ... make alarm causal ...
    alarm = gmtime(&atime);
    if (alarm->tm_sec > 59) alarm->tm_sec = 59; // ... skip any leap seconds if any ...
    buffer[1] = int2bcd(alarm->tm_sec); // and write seconds
    buffer[2] = int2bcd(alarm->tm_min); // minutes
    buffer[3] = int2bcd(alarm->tm_hour); // hour
    buffer[4] = int2bcd(alarm->tm_wday+1); // day of week
    buffer[4] |= ALARMMC; // add alarm match condition and write
    buffer[5] = int2bcd(alarm->tm_mday); // day of month
    buffer[6] = int2bcd(alarm->tm_mon+1); // month
  }
  /* open i2c device */
  snprintf(i2cdevicename, 11, "/dev/i2c-%d", i2cbus);
  file = open(i2cdevicename, O_WRONLY);
  if (file < 0) {
    printf("Error: Can't open /dev/i2c-%d.\n", i2cbus);
    exit(4);
  }
  if (ioctl(file, I2C_SLAVE_FORCE, MCP7941X) < 0) {
    printf("Error: Can't attach I2C Client 0x%x.\n", MCP7941X);
    exit(5);
  }
  /* write alarm0 to RTC */
  buffer[0] = ALARM0REG; // set ALARM0 register address
  if (write(file, buffer, ALARMREGSETLEN+1) != ALARMREGSETLEN+1) {
    printf("Error: Can't write alarm to I2C Client 0x%x.\n", MCP7941X);
    exit(6);
  }
  /* activate alarm and deactivate power rail */
  cbuffer[0] = CTRLREG; // set RTC control register address
  if (write(file, cbuffer, 2) != 2) {
    printf("Error: Can't write configuration to I2C Client 0x%x.\n", MCP7941X);
    exit(7);
  }
  exit(0);
}

Weckruf

Beim Systemstopp – am einfachsten initiiert mit sudo halt – erwartet das Skript aus Listing 6 die Weckzeit in der Datei /etc/wakealarm als Anzahl der Sekunden seit dem 1. Januar 1970 um 00:00:00 UTC [6]. Listing 9 zeigt, wie Sie eine absolute Weckzeit am Weihnachtsabend oder eine relative von der Kommandozeile aus anlegen.

Listing 9

 

$ sudo sh -c 'date -d "2014-12-24 17:59:30" +%s > /etc/wakealarm'
$ sudo sh -c 'echo $((`date +%s` + (7 * 60 + 11) * 60 + 13)) > /etc/wakealarm'

Das Wecken deaktivieren Sie durch das Löschen dieser Datei oder indem Sie die Weckzeit auf 0 setzen.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 8 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Raspberry Pi Geek kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

Aktuelle Ausgabe

06/2019
Home Improvement

Diese Ausgabe als PDF kaufen

Preis € 9,99
(inkl. 19% MwSt.)

Stellenmarkt

Neuigkeiten

  • Verschlungene Pfade

    Mit Schleifen, Fallunterscheidungen und Funktionen programmieren Sie komplexe Skripte auf einfache und elegante Weise.

  • Extrem genau

    Mit einem A/D-Wandler messen Sie bei Bedarf Spannungen. Der MCP3424 macht dabei konstruktionsbedingt eine gute Figur.

  • Verbindungsaufnahme

  • Süßer Wecker

    Dem RasPi fehlen sowohl eine Echtzeituhr als auch ein BIOS, ein zeitgesteuertes Wecken erfordert also Zusatzkomponenten. Hier springt der Witty Pi Mini in die Bresche, ein µHAT von UUGear.

  • Windows to go

    Das Aufsetzen zuverlässiger und sicherer Remote-Desktop-Lösungen erfordert einiges Know-how. Die RasPi-basierte Pinbox von Pintexx reduziert den Konfigurationsaufwand auf ein Minimum.

  • Prima Klima

    In Museen ist es Pflicht, zu Hause nützlich: das permanente Prüfen und zentrale Erfassen der Feuchtigkeit und Temperatur in Räumen.

  • Auf einen Blick

    Ein maßgeschneiderter Infoscreen auf RasPi-Basis mit stromsparendem E-Ink-Display zeigt Termine, Bilder, Mitteilungen und Wetterinformationen an.

  • Sanft berührt

    Mit einem RasPi und dem Controllermodul PiXtend lassen sich mühelos Roboterarme ansteuern und deren Bewegung automatisieren.

  • Popcorn-Kino

    Mit Kodi 18.0 unterstützt LibreELEC 9.0 jetzt die von vielen Streaming-Diensten genutzte DRM-Verschlüsselung. Die Integration von Netflix, Amazon und Co. erfordert allerdings Handarbeit.

  • So nah und doch so fern

    Der RasPi kommt häufig als Server oder Steuerrechner für spezielle Zwecke zum Einsatz. Mit Anydesk erhalten Sie dazu eine Steuersoftware mit grafischer Oberfläche.