4

On my Beaglebone Black I added a I2C real-time-clock to not being reliant on ntpd to maintain accurate timing. The outcome is that there are two special device files in /dev. These are /dev/rtc0 and /dev/rtc1 but there is also /dev/rtc which is a symlink to /dev/rtc0.

enter image description here

/dev/rtc0 is the real-time-clock within the ARM SOC on the board, /dev/rtc1 is the I2C device. At the moment I'm using scripts that read and write the time manually to the I2C clock but I'd rather like the symlink /dev/rtc to point to /dev/rtc1.

Hence the question, how can this be done? The Linux distro on my beaglebone black is Arch Linux which uses systemd for all the house keeping.

When I delete the symlink and create a new one pointing to /dev/rtc1 not surprisingly it is reset after the next reboot and I didn't find any config files or systemd-units so far.

Help is much appreciated.

1

2 Answers 2

4

That udev rule hint pointed me in the right direction. After a quick review of writing udev rules I did the following.

udevadm info -a -p /sys/class/rtc/rtc1

The output (shortened) revealed some useful properties to define a udev rule.

looking at device '/devices/platform/ocp/4802a000.i2c/i2c-1/1-0068/rtc/rtc1':
KERNEL=="rtc1"
SUBSYSTEM=="rtc"
DRIVER==""
ATTR{date}=="2015-12-04"
ATTR{hctosys}=="0"
ATTR{max_user_freq}=="64"
ATTR{name}=="ds1307"
ATTR{since_epoch}=="1449230817"
ATTR{time}=="12:06:57"
...

So the rules file needs to reside in /etc/udev/rules.d/ with a naming scheme like 99-rtc1.rules.

The files content is

KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="ds1307", SYMLINK="rtc", MODE="0666"

To test the rule you can run

udevadm test /sys/class/rtc/rtc1

and the important lines in the output are

...
creating link '/dev/rtc' to '/dev/rtc1'
atomically replace '/dev/rtc'
...

The result in /dev is the desired configuration.

enter image description here

0

After trying many things to get my I2C RTC working on a Orange Pi PC plus with a builtin RTC, I've managed (a nasty way) to have it working.

  1. Find out the path to the built-in rtc:
#>find /sys | egrep 'rtc$'
/sys/bus/platform/drivers/sun6i-rtc/1f00000.rtc

You'll probably get many lines, just focus on the ones with "/sys/bus..."

  1. Create a udev to manage the creation of the device and device links
#>nano /etc/udev/rules.d/99-rtc1.rules

Paste this content:

KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="rtc-ds1307 0-0068", ATTR{hctosys}=="0", SYMLINK+="rtc", SYMLINK+="rtc0", MODE="0666"
  1. Now, you have to create a systemd service:
#>nano /etc/systemd/system/rtc.service

The below content has to be edited according to your rtc0 built-in and rtc1 i2c devices on the line ExecStart:

[Unit]
Description=Initialize ds1307 RTC and sincronize system clock
DefaultDependencies=no
Requires=systemd-modules-load.service
After=systemd-modules-load.service
#Before=sysvinit.target
ConditionPathExists=/sys/class/i2c-adapter
#Conflicts=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=root
WorkingDirectory=/root
ExecStart=/bin/sh -c "echo -n "1f00000.rtc" > /sys/bus/platform/drivers/sun6i-rtc/unbind && echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device && hwclock --rtc /dev/rtc --hctosys --utc"

[Install]
WantedBy=multi-user.target
  1. Enable the service: #>systemctl enable rtc.service
  2. Start the service: #>systemctl start rtc.service
  3. You may check if the /dev/rtc* devices have changed accordingly using ls -lah /dev/rtc* you should have something like this:
lrwxrwxrwx 1 root root      4 Apr  3 18:19 /dev/rtc -> rtc1
lrwxrwxrwx 1 root root      4 Apr  3 18:19 /dev/rtc0 -> rtc1
crw-rw-rw- 1 root root 253, 1 Apr  3 18:19 /dev/rtc1

Now rtc and rtc0 are pointing to rtc1!

  1. Check if hwclock is working with hwclock --verbose
hwclock from util-linux 2.37.2
System Time: 1680548612.161304
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Last drift adjustment done at 1680540088 seconds after 1969
Last calibration done at 1680540088 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
ioctl(4, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2023/04/03 19:03:33
Hw clock time : 2023/04/03 19:03:33 = 1680548613 seconds since 1969
Time since last adjustment is 8525 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2023-04-03 19:03:32.766066+00:00

To update your clock with system time just use hwclock -w to update from rtc use hwclock -s

You must add your module to the /etc/modules echo "rtc-ds1307" >> /etc/modules

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Apr 3, 2023 at 19:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .