Just updated to Raspbian stretch and my ds3231 will not update the system clock on reboot - i suspect that the command /sbin/hwclock -s is not working in /etc/rc.local - if I just do the update manually sudo hwclock -s the system date time updates ok - i have seen post but not really seen an understandable fix for this iussue - can any one advise with a fix please? - my older version 4.9.35+ is ok but this version 4.9.59+ is giving me the problems - thanks
3 Answers
I have this:
uname -a
Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l GNU/Linux
I did this:
sudo apt-get install -y python-smbus i2c-tools
Added this last in /boot/config.txt:
dtoverlay=i2c-rtc,ds3231
Then:
sudo apt-get -y remove fake-hwclock
sudo update-rc.d -f fake-hwclock remove
Then edit /lib/udev/hwclock-set and comment out:
#if [ -e /run/systemd/system ] ; then
# exit 0
#fi
Now I am going continue with my script that detects chip type (ds3231 and pcf8523) and does this automatically...
More info here: https://cdn-learn.adafruit.com/downloads/pdf/adding-a-real-time-clock-to-raspberry-pi.pdf
EDIT:
I am done with the script now, thought I'd share the result. It handles ds3231 and pcf8523. Comments are in English but feedback from the script is in Swedish (I have to be nice to the users). It removes the dtoverlay line from /boot/config.txt because it must use i2c in raw mode to be able to determine what chip it is. When it can detect the chip it adds the correct dtoverlay line. You may also find the following commands helpful when testing if the system time is set by the RTC upon boot:
sudo systemctl disable systemd-timesyncd.service
sudo systemctl enable systemd-timesyncd.service
sudo systemctl status systemd-timesyncd.service
The script, now dynamically unloads and loads the drivers:
#!/bin/bash
# installrtc.sh
# Install packages needed for ITC communication
#sudo apt-get install -y python-smbus i2c-tools
# Try to unload RTC modules dynamically so we do not have to reboot
printf 'Drivrutin laddas ur\n'
sudo modprobe -r rtc_pcf8523 2>/dev/null
sudo modprobe -r rtc_ds1307 2>/dev/null
printf 'Drivrutin plockas bort från /boot/config.txt\n'
sudo sed -i '/dtoverlay=i2c-rtc,ds3231/d' /boot/config.txt
sudo sed -i '/dtoverlay=i2c-rtc,pcf8523/d' /boot/config.txt
# Dump I2C chip map, get the 8th line, then get the 10th field (separated by spaces)
CHIP_PRESENCE=$(sudo i2cdetect -y 1 | sed -n '8p' | cut -d ' ' -f10)
case $CHIP_PRESENCE in
68) printf 'Klockchip hittades\n'
;;
00) printf 'Klockchip hittades inte!\n'
exit 1
;;
UU) printf 'Drivrutin for klockchip redan laddad. Kan inte avgora typ av klocka.\n'
exit 1
;;
esac
printf 'Detekterar typ av klockchip ... '
LAST_CAND1=$(sudo i2cdump -y -r 0x00-0x0f 1 0x68 c | sed -n '2p' | cut -d ' ' -f2)
LAST_CAND2=$(sudo i2cdump -y -r 0x00-0x0f 1 0x68 c | sed -n '2p' | cut -d ' ' -f5)
cand1=0
cand2=0
testcount=1
while [ $testcount -le 3 ]
do
printf '%d ' $((3 - $testcount))
#sudo i2cdump -y -r 0x00-0x0f 1 0x68 c
sleep 2
SEC_CAND1=$(sudo i2cdump -y -r 0x00-0x0f 1 0x68 c | sed -n '2p' | cut -d ' ' -f2)
SEC_CAND2=$(sudo i2cdump -y -r 0x00-0x0f 1 0x68 c | sed -n '2p' | cut -d ' ' -f5)
if [ "$SEC_CAND1" != "$LAST_CAND1" ]; then
let "cand1++"
fi
if [ "$SEC_CAND2" != "$LAST_CAND2" ]; then
let "cand2++"
fi
#echo "$SEC_CAND1 $cand1 $SEC_CAND2 $cand2"
LAST_CAND1=$SEC_CAND1
LAST_CAND2=$SEC_CAND2
#sudo i2cdump -y -r 0x00-0x0f 1 0x68 c | sed -n '2p'
let "testcount++"
done
if [ "$cand1" -ge "2" ] && [ "$cand2" -ge "2" ]; then
printf '\nFEL! Bada chiptypernas sekundregister forandrades.\n'
printf 'Det gick inte att avgora vilket klockchip som ar monterat.\n'
exit 1
elif [ "$cand1" -ge "2" ]; then
printf -- '- klockchip = DS3231\n'
sudo sed -i -e "\$adtoverlay=i2c-rtc,ds3231" /boot/config.txt
sudo modprobe rtc_ds1307
printf 'Drivrutin laddad och aktiverad.\n'
elif [ "$cand2" -ge "2" ]; then
printf -- '- klockchip = PCF8523\n'
sudo sed -i -e "\$adtoverlay=i2c-rtc,pcf8523" /boot/config.txt
sudo modprobe rtc_pcf8523
printf 'Drivrutin laddad och aktiverad.\n'
else
printf '\nFEL! Ingen av chiptypernas sekundregister forandrades.\n'
printf 'Det gick inte att avgora vilket klockchip som ar monterat.\n'
exit 1
fi
While you can use rc.local
in a systemd
the results may be unpredictable as systemd
services run acynchronously.
The ONLY thing you have to do is include in /boot/config.txt:
dtoverlay=i2c-rtc,ds3231
DO NOT modprobe, blacklist or disable fake-hwclock.
Milliways, since I can't comment yet I had to add another anwser. modprobe -r lets me unload so I can get raw data from the RTC chips to determine which one it is. blacklist I didn't do or even mention. fake-hwclock, isn't that the thing that saves the clock to a file and restores it? It won't help in my read-only setup with no reachable ntp. Anyway I don't need any fake time at all. 1970 is better than a faked time.
I have been reading for hours about the Device Tree, I am searching for a way to dynamically unload/load i2c-rtc but I have not found a solution.
-
Instead of removing the driver module, you can simply tell the driver to ignore a certain I2C chip:
echo 0x68 >/sys/bus/i2c/devices/i2c-0/delete_device
You reassign the chip to the i2c-rtc driver by doingecho i2c-rtc 0x68 >/sys/bus/i2c/devices/i2c-0/new_device
– JankaCommented Feb 18, 2018 at 0:04