1

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

1

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
0

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.

0

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 doing echo i2c-rtc 0x68 >/sys/bus/i2c/devices/i2c-0/new_device – Janka Feb 18 '18 at 0:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.