How to automatically set system time of BBB by external DS3231

Hi,

I am using beagle Bone Black with debian image. Could any please suggest how to automatically set the system time (on every reboot) by external RTC module DS3231. Once internet is connected, i want to update both system time and DS3231 with the network time.

I am controlling a relay based on system time, my application should take DS3231 time and run perfectly even if internet is disconnected and not available for so many days.

Few things i have tried, the following content has been kept in the script and running @reboot script in crontab. The system time has been changed if we enter this command manually after boot but not in auto start script. Please advice.

echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device

hwclock -r -f /dev/rtc1

Best regards,

NK

Hi,

I am using beagle Bone Black with debian image. Could any please suggest
how to automatically set the system time (on every reboot) by external RTC
module DS3231. Once internet is connected, i want to update both system
time and DS3231 with the network time.

I am controlling a relay based on system time, my application should take
DS3231 time and run perfectly even if internet is disconnected and not
available for so many days.

Few things i have tried, the following content has been kept in the script
and running @reboot script in crontab. The system time has been changed if
we enter this command manually after boot but not in auto start script.
Please advice.

*echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device*

*hwclock -r -f /dev/rtc1*

Well, the simple / dumb option would be to put the above two lines in
/etc/rc.local, which will restore the system clock from the RTC.

The other option is to create a proper RTC service. A properly setup RTC
service will restore the system clock from the RTC early in the boot process
and save the system clock late in the shutdown process.

A proper RTC service is already implemented by the systemd-timesyncd service, installed by default on the debian images:
https://www.freedesktop.org/software/systemd/man/systemd-timesyncd.service.html

It does everything Niresh needs out of box. There’s a caveat: systemd-timesyncd only works with /dev/rtc0 device. By default /dev/rtc0 is grabbed by the AM335x CPU-s internal RTC (which has no battery backup) and the external RTC is left with /dev/rtc1 which gets ignored. I did not find any way to configure systemd-timesyncd to use the other device.

Robert pointed me to a device tree which very conveniently swapped the device nodes for those RTCs so the external one got /dev/rtc0. I just had to load the device tree via /boot/uEnv.txt and time syncing worked beautifully. For Niresh, I suggest trying this one:

https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/BB-I2C2-RTC-DS3231.dts

To clarify the “trying” step: you’ll probably find the compiled device tree in the Beagle’s file system: “/lib/firmware/BB-I2C2-RTC-DS3231.dtb”. Just add this to /boot/uEnv.txt using standard method and reboot. Monitoring the boot log via dmesg should tell you which RTC device was awarded /dev/rtc0.

Hi,
1). I have placed the following lines in the /etc/rc.local, and system time gets updated with external RTC DS3231 automatically at every reboot

echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device

hwclock -s -f /dev/rtc1

dtb_overlay = /lib/firmware/BB-I2C2-RTC-DS3231.dtbo

Hi,

I have put the line dtb_overlay = /lib/firmware/BB-I2C2-RTC-DS3231.dtbo in /boot/uEnv.txt but it does not create /dev/rtc1. The dmesg are

root@beaglebone:/dev# dmesg | grep 3231

[ 2.132312] console [ttyS0] enabled

root@beaglebone:/dev# dmesg | grep rtc

[ 2.221605] omap_rtc 44e3e000.rtc: already running

[ 2.222249] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0

[ 2.572035] PM: bootloader does not support rtc-only!

[ 2.573042] omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 02:14:15 UTC (946692855)

root@beaglebone:/dev# dmesg | grep rtc1

root@beaglebone:/dev#

root@beaglebone:/dev# dmesg | grep rtc

[ 2.221605] omap_rtc 44e3e000.rtc: already running

[ 2.222249] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0

[ 2.572035] PM: bootloader does not support rtc-only!

[ 2.573042] omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 02:14:15 UTC (946692855)

root@beaglebone:/dev# date

Tue Jul 14 13:07:39 IST 2020

root@beaglebone:/dev# hwclock -r -f /dev/rtc

Sat 01 Jan 2000 07:46:54 AM IST -0.651632 seconds

Hi,
1). I have placed the following lines in the /etc/rc.local, and system time gets updated with external RTC DS3231 automatically at every reboot

echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device

hwclock -s -f /dev/rtc1

  1. I have put the line dtb_overlay = /lib/firmware/BB-I2C2-RTC-DS3231.dtbo in /boot/uEnv.txt but it does not create /dev/rtc1 and system time not updated with external RTC DS3231. The dmesg are

root@beaglebone:/dev# dmesg | grep 3231

[ 2.132312] console [ttyS0] enabled

root@beaglebone:/dev# dmesg | grep rtc

[ 2.221605] omap_rtc 44e3e000.rtc: already running

[ 2.222249] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0

[ 2.572035] PM: bootloader does not support rtc-only!

[ 2.573042] omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 02:14:15 UTC (946692855)

root@beaglebone:/dev# dmesg | grep rtc1

root@beaglebone:/dev#

root@beaglebone:/dev# dmesg | grep rtc

[ 2.221605] omap_rtc 44e3e000.rtc: already running

[ 2.222249] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0

[ 2.572035] PM: bootloader does not support rtc-only!

[ 2.573042] omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 02:14:15 UTC (946692855)

root@beaglebone:/dev# date

Tue Jul 14 13:07:39 IST 2020

root@beaglebone:/dev# hwclock -r -f /dev/rtc

Sat 01 Jan 2000 07:46:54 AM IST -0.651632 seconds

Best regards,

NK

Please run:

sudo /opt/scripts/tools/version.sh

and share it's output, so we can comment on your configuration.

Regards,

Did you make changes to that .dts and properly rebuild it and install it with the install.sh script?

If it's in the uEnv.txt file properly, it should be loaded. That overlay is pre-built into the initrd.img.

We did not make any changes to the .dts file. uEnv.txt file attached for your reference.

There is no script “verison.sh” in the path /opt/scripts/tools/ in kernel version 4.4.30-ti-r64.

uEnv.txt (1.53 KB)

Wow, you’re running a rather old Debian release. The stuff that I suggested was likely not implemented back then. I would upgrade to a recent Debian release:
http://beagleboard.org/getting-started

Note to whoever maintains beagleboard.org: the Letsencrypt SSL cert expired 3 days ago.

Then the version of u-boot is way way way to old. PS, on a newer image
this wouldn't work:

dtb_overlay = /lib/firmware/BB-I2C2-RTC-DS3231.dtbo
->
dtb_overlay=/lib/firmware/BB-I2C2-RTC-DS3231.dtbo

U-Boot's parser doesn't like the "space"...

Feel Free to upgrade.

Regards,

1). I have placed the following lines in the /etc/rc.local, and system
time gets updated with external RTC DS3231 automatically at every reboot

*echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device*

...

2) I have put the line *dtb_overlay =
/lib/firmware/BB-I2C2-RTC-DS3231.dtbo * in /boot/uEnv.txt but it does not

the overlay you're using won't work because your rtc chip is
on i2c bus one: as its name (...I2C2...) indicates it's for a
clock chip being on i2c bus two.

use dtc to decompile that overlay, edit for i2c1 and dtc it back into
binary form.

Good catch, although it’s probably not necessary to decompile binary trees as the source is available here together with a nice makefile to build a single overlay:
https://github.com/beagleboard/bb.org-overlays

Without having tested it, I might imagine a process similar to this one:

$ git clone https://github.com/beagleboard/bb.org-overlays.git $ cd bb.org-overlays $ cp src/arm/BB-I2C2-RTC-DS3231.dts src/arm/BB-I2C1-RTC-DS3231.dts $ vim src/arm/BB-I2C1-RTC-DS3231.dts ... update I2C bus number ... $ make src/arm/BB-I2C1-RTC-DS3231.dtbo $ cp src/arm/BB-I2C1-RTC-DS3231.dtbo /lib/firmware

Hi,
I am a newbie to the linux environment and BBB, your information is very helpful.

I’ve have tested both BB-I2C1-RTC-DS3231.dtbo and BB-I2C2-RTC-DS3231.dtbo in the new image 4.19.94-ti-r42, they mount rtc1 in /dev but system time is not updated with rtc1. Please let me know if any other procedure is required and also procedure to update external rtc1 time when the internet is connected.

One thing i have observed, with BB-I2C1-RTC-DS3231.dtbo the timedatectl command displayed “RTC time: n/a” not system time as in normal condition.

Please clarify the following points

  1. How do you say the rtc chip is in i2c bus one. Using i2cdetect command “i2cdetect -r 2” , 0x68 external device showed in i2c bus two.
  2. I understand overlay is an out of box approach. In 4.4.30-ti-r64, system time updated with “echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device; hwclock -r -f /dev/rtc1” in /etc/rc.local. Is there any problem if I use this approach in older images?

Regards,

NK

I’ve have tested both BB-I2C1-RTC-DS3231.dtbo and BB-I2C2-RTC-DS3231.dtbo in the new image 4.19.94-ti-r42, they mount rtc1 in /dev but system time is not updated with rtc1. Please let me know if any other procedure is required and also procedure to update external rtc1 time when the internet is connected.

That’s unfortunate. Still, logs from the uboot bootloader (observed from the onboard TTL level UART) or the Linux kernel (from dmesg or syslog) might indicate what’s wrong.

To get effective help, please post output from “sudo /opt/scripts/tools/version.sh” and the content of your “/boot/uEnv.txt” file.

One thing i have observed, with BB-I2C1-RTC-DS3231.dtbo the timedatectl command displayed “RTC time: n/a” not system time as in normal condition.

Weird. I would interpret it as the AM335x internal RTC having been pushed aside from /dev/rtc0 successfully, but the external RTC does not pick the device up.

Please clarify the following points

  1. How do you say the rtc chip is in i2c bus one. Using i2cdetect command “i2cdetect -r 2” , 0x68 external device showed in i2c bus two.

There might be differences in how different systems count buses. One might start from 0 and other from 1. TBH it’s always been confusing as hell for me.

  1. I understand overlay is an out of box approach. In 4.4.30-ti-r64, system time updated with “echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device; hwclock -r -f /dev/rtc1” in /etc/rc.local. Is there any problem if I use this approach in older images?

No, go right ahead. You’re left with the task of figuring out a solution for syncing time between the RTC, system clock and NTP - as you wrote out in the very first message. My suggestion was to have systemd-timesyncd do it for you, but you can, as an alternative, do it yourself with a few bash scripts.

Every RTC clock is a little different, but sometimes it seems like you
have to "force" the first date write, try a few of these random
commands. :wink:

https://www.thegeekstuff.com/2013/08/hwclock-examples/

Regards,

Hi,

Attached output from “sudo /opt/scripts/tools/version.sh” and the content of your “/boot/uEnv.txt” file along with boot log message.

debian@beaglebone:/boot$ dmesg | grep rtc1

[ 2.285972] omap_rtc 44e3e000.rtc: registered as rtc1

debian@beaglebone:/boot$ dmesg | grep rtc

[ 2.283660] rtc-ds1307: probe of 1-0068 failed with error -16

[ 2.285972] omap_rtc 44e3e000.rtc: registered as rtc1

[ 2.574770] [drm] Cannot find any crtc or sizes

[ 2.603277] hctosys: unable to open rtc device (rtc0)

[ 3.592324] [drm] Cannot find any crtc or sizes

[ 57.824450] PM: rtc0 not available

[ 59.781548] PM: rtc0 not available

[ 59.958344] PM: rtc0 not available

[ 60.042066] PM: rtc0 not available

debian@beaglebone:/boot$

Please help me with bash scripts for external RTC and its procedure.

Regards,
NK

Content of Version-sh.txt (2.71 KB)

uEnv.txt (2.17 KB)

DMSGS.TXT (306 KB)

Hi Niresh,

Attached output from “sudo /opt/scripts/tools/version.sh” and the content of your “/boot/uEnv.txt” file along with boot log message.

They look good. I suspect you’re mostly there :slight_smile:

debian@beaglebone:/boot$ dmesg | grep rtc

[ 2.283660] rtc-ds1307: probe of 1-0068 failed with error -16

This indicates that the device tree was loaded correctly, but the kernel can’t talk to your RTC chip. If you can figure out why, you’ve enabled systemd-timesyncd.

Hmm, can you double-check that the I2C bus number is correct and the RTC chip is online?

There is a utility called i2cdetect which should reveal your RTC on bus 1, address 68.

Please help me with bash scripts for external RTC and its procedure.

Undo your changes to uEnv.txt and follow this guide instead. It’s not ideal, but probably covers the relevant requirements.

Hi,

debian@beaglebone:/dev$ i2cdetect -r -y 2

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: – -- – -- – -- – -- – -- – -- –

10: – -- – -- – -- – -- – -- – -- – -- – --

20: – -- – -- – -- – -- – -- – -- – -- – --

30: – -- – -- – -- – -- – -- – -- – -- – --

40: – -- – -- – -- – -- – -- – -- – -- – --

50: – -- – -- – -- – UU – -- – -- – -- – --

60: – -- – -- – -- – -- 68 – -- – -- – -- –

70: – -- – -- – -- – --

debian@beaglebone:/dev$ i2cdetect -r -y 1

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: – -- – -- – -- – -- – -- – -- –

10: – -- – -- – -- – -- – -- – -- – -- – --

20: – -- – -- – -- – -- – -- – -- – -- – --

30: – -- – -- – -- – -- – -- – -- – -- – --

40: – -- – -- – -- – -- – -- – -- – -- – --

50: – -- – -- – -- – -- – -- – -- – -- – --

60: – -- – -- – -- – -- – -- – -- – -- – --

70: – -- – -- – -- – --

debian@beaglebone:/dev$ i2cdetect -r -y 0

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: – -- – -- – -- – -- – -- – -- –

10: – -- – -- – -- – -- – -- – -- – -- – --

20: – -- – -- UU – -- – -- – -- – -- – -- –

30: – -- – -- 34 – -- – -- – -- – -- – -- –

40: – -- – -- – -- – -- – -- – -- – -- – --

50: UU – -- – -- – -- – -- – -- – -- – -- –

60: – -- – -- – -- – -- – -- – -- – -- – --

70: UU – -- – -- – -- –

debian@beaglebone:/dev$

Regards,

NK