For those, who cannot read the posts in the Raspberry Pi forum, I'm posting the same little turorial on how to setup the mechanism to correctly read the date and time from an RTC chip hooked up on the GPIO pins of your RPi device and keep it syncronised with NTP.
I've tested this on Debian Jessie and UbuntuMATE 15.10 and seems to be working fine on my devices.
1st approach:
If sticking to the classical “services” start-up mechanism as it comes today preinstalled, then the file “/lib/udev/hwclock-set” can be modified with the following contents:
[code]#!/bin/sh
File: /lib/udev/hwclock-set
Called by: /lib/udev/rules.d/85-hwclock.rules
Reset the System Clock to UTC if the hardware clock from which it
was copied by the kernel was in localtime.
dev=$1
if [ -e /run/udev/hwclock-set ]; then
exit 0
fi
if [ -f /etc/default/rcS ] ; then
. /etc/default/rcS
fi
These defaults are user-overridable in /etc/default/hwclock
BADYEAR=no
HWCLOCKACCESS=yes
HWCLOCKPARS=
HCTOSYS_DEVICE=rtc0
BLACKLIST=blacklist.conf
if [ -f /etc/default/hwclock ] ; then
. /etc/default/hwclock
fi
check if RTC chip is already discovered with "dtoverlay=i2c-rtc,ds3231" in /boot/config.txt
if [ ! "cat /proc/modules | grep rtc | grep -i live
" ]; then
remove module from "blacklist.conf" if existant
[ -f /etc/modprobe.d/$BLACKLIST ] && sed -n -i 's/blacklist i2c-bcm2708/#blacklist i2c-bcm2708/' /etc/modprobe.d/$BLACKLIST
load i2c kernel modules if not already loaded with "dtparam=i2c" in /boot/config.txt
[ "cat /proc/modules | grep i2c_bcm2708 | grep -i live
" ] || modprobe -q i2c-bcm2708
fi
iterate over every i2c bus as we're supporting Raspberry Pi rev. 1 and 2 (different I2C busses on GPIO header!)
[ "cat /proc/modules | grep i2c_bcm2708 | grep -i live
" ] && for i in ls -1 /sys/class/i2c-adapter
; do
if [ $i ]; then
[ -w /sys/class/i2c-adapter/$i/new_device ] && echo ds3231 0x68 >> /sys/class/i2c-adapter/$i/new_device
wait at least 1 second time (1 clock tick) to ensure device file creation
sleep 1
if [ -e /dev/$HCTOSYS_DEVICE ]; then
if [ yes = "$BADYEAR" ]; then
/sbin/hwclock --rtc=$dev --hctosys --badyear
else
/sbin/hwclock --rtc=$dev --hctosys
fi
else
[ -w /sys/class/i2c-adapter/$i/delete_device ] && echo 0x68 >> /sys/class/i2c-adapter/$i/delete_device
fi
fi
done
Note 'touch' may not be available in initramfs
/run/udev/hwclock-set[/code]
See the Debian Bug Report # 764552 on further details why the contents of the file “/lib/udev/hwclock-set” needs to be modified.
2nd approach:
If you like to take another approach using the “systemd” mechanism, then follow these steps:
Edit the file “/boot/config.txt” and add a similar line like “dtoverlay=i2c-rtc,ds3231” to instruct the kernel to create the device file for the RTC chip DS3231.
On the shell prompt and with “root” privileges, type the following commands:
systemctl stop hwclock.sh fake-hwclock ntp
systemctl disable hwclock.sh fake-hwclock ntp
systemctl mask hwclock.sh fake-hwclock ntp
Create a file “/etc/systemd/system/hwclock-sync.service” with the following contents:
[code][Unit]
Description=Time Synchronization from RTC Source
After=systemd-modules-load.service
RequiresMountsFor=/dev/rtc
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/sbin/hwclock -s
TimeoutSec=0
[Install]
WantedBy=time-sync.target[/code]
Edit the file “/etc/rc.local” and add the following line:
[ ! -e /var/lib/systemd/clock -a "`systemctl is-active systemd-timesyncd | grep -i active`" ] && timedatectl set-ntp 1 > /dev/null 2>&1
Create or edit the file “/etc/systemd/timesyncd.conf” with the following contents:
[Time]
NTP=0.europe.pool.ntp.org 1.europe.pool.ntp.org 2.europe.pool.ntp.org 3.europe.pool.ntp.org
FallbackNTP=0.europe.pool.ntp.org 1.europe.pool.ntp.org 2.europe.pool.ntp.org 3.europe.pool.ntp.org
Back at the shell prompt, type the following command to enable the automatic start-up during boot of the services for the time synchronisation from the RTC chip and also from an NTP source if connected to the Internet:
systemctl enable hwclock-sync systemd-timesyncd
The following command will manually startup the described services from the shell prompt:
systemctl start hwclock-sync systemd-timesyncd
With this approach, we leave it up to "systemd" to start up the relevant services for date and time synchronisation from an RTC source and from an NTP source, the "timesyncd" service will take care to synchronise the RTC chip with the date and time settings obtained from NTP.
You can verify this by executing the following command on the shell prompt:
timedatectl
The output from this command shall be similar to the following:
Local time: Wed 2015-11-18 09:44:46 CET
Universal time: Wed 2015-11-18 08:44:46 UTC
RTC time: Wed 2015-11-18 08:44:46
Time zone: … (CET, +0100)
Network time on: yes
NTP synchronized: yes
RTC in local TZ: no
The legacy services "fake-hwclock" and "ntp" can be deinstalled, since no longer required
Hope this helps