Restoring system time from RTC shield on boot

Post Reply
e-pirate
Posts: 7
Joined: Thu Apr 18, 2019 6:09 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 2 times
Contact:

Restoring system time from RTC shield on boot

Post by e-pirate »

Hi, folks!
Recently I spent a lot of time playing with PCF8563 RTC Shield on my C2 board. In my case correct system time is absolutely vital for my project. To keep the time accurate I use local NTP server and chronyd as NTP client, but as power failures still can brake this I decided to use RTC as power independent time source for the system. I had no problems with the hardware part, just fallowed the Wiki page. With the only exception of actual time setup during system boot process. I found the suggested method using rc.local totally incorrect because of late system clock setup and logs drops.
The systemd utilized in Ubuntu 18 passes several "targets" during boot process including execution of rc.local script, but this happens way to late after kernel start up and early system initialization. System is started with some predefined time in 2018 (in my case), boots the kernel, starts some initial services and then finally reaches local.rc, updates the system clock which makes journald discard all logs including very valuable kernel and early system initialization logs. This seems to happen because of sudden time jump from past to actual date and last saved messages to be in the future compared to the "predefined" time. So, we end up with logs starting in the middle of the boot process. In some cases if rc.local is executed after system logger (syslogd or syslog-ng) started (this is possible because there is no dependency chain), we have no logs at all: log will end with the last shutdown message and not a single new line after. While the system is functional, this could be considered as major failure as there partial or no logs make some investigations impossible.
How Ironically, but this is the case, actually. I was trying to figure out what's going on with the logs... without logs. I had no way to figure out the boot order and what actually happening because most interesting part prior time setup was discarded by journald. If I booted the system without time update, I had no logs at all. But during my exhausting 2 day experiments I managed somehow to write a correct Before-After dependency chain and finally got the whole boot process from the very first kernel message. That allowed me to figure out the exact order of "targets" and services start. The I figured out, that journald (that's obvious, yah) is responsible for logs collecting and saving. More over, if I can somehow update time before journald is started, it will start in actual "present" times leading to all logs to be correctly handled including kernel start up logs. The rest was pretty straight forward:
Just create /lib/systemd/system/hwrtc.service with the fallowing content:

Code: Select all

[Unit]
Description=Synchronise System clock to hardware RTC
DefaultDependencies=no
After=systemd-modules-load.service
Before=systemd-journald.service time-sync.target sysinit.target shutdown.target
Conflicts=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/hwclock --hctosys --utc --noadjfile
RestrictRealtime=yes

[Install]
WantedBy=sysinit.target
Then enable this service to be stated during boot process:

Code: Select all

systemctl enable hwrtc
To be mentioned, there are many (including my on AskUbuntu) similar questions/topics on the Net from people trying to overcome this problem on different SBCs with no universal working solution. Most of them have wrong target (commonly advised "multi-user" is late), wrong After-Before dependency chain or both. All this makes hwclock to be executed after journald leading to partial or all logs to be droped. Besides, make sure that all necessary kernel modules are listed in /etc/modules or /etc/modules-load.d/.
This service will execute hwclock and set system clock from RTC before sysinit target and journald so from the journald point of view all the messages will have actual timestamps and will be saved in logs providing you with all possible boot information.
Besides, there is no ExecStop command which usually saves current system to RTC on shutdown. The reason behind this is that IMHO this should be handled by NTP client. Both ntpd-client and chronyd will activate "11 minute" kernel mode that saves system time to RTC as soon as NTP sync state reached.
IMHO, the wiki page should be updated with this method.
These users thanked the author e-pirate for the post:
neal (Tue Jan 12, 2021 10:00 am)

mad_ady
Posts: 9049
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, C4, N1, N2, H2, Go, Go Advance
Location: Bucharest, Romania
Has thanked: 595 times
Been thanked: 573 times
Contact:

Re: Restoring system time from RTC shield on boot

Post by mad_ady »

I agree, it should be added to the wiki. I didn't know journald discarded logs on time jump...

User avatar
neal
Posts: 244
Joined: Fri Apr 14, 2017 10:02 am
languages_spoken: Korean, English
Has thanked: 9 times
Been thanked: 18 times
Contact:

Re: Restoring system time from RTC shield on boot

Post by neal »

That's worth it. I will check it and update the wiki once I've figured it out.

User avatar
neal
Posts: 244
Joined: Fri Apr 14, 2017 10:02 am
languages_spoken: Korean, English
Has thanked: 9 times
Been thanked: 18 times
Contact:

Re: Restoring system time from RTC shield on boot

Post by neal »

Updated PCF8563 RTC module wiki page.
https://wiki.odroid.com/accessory/add-o ... rtc_shield
Thanks @e-pirate ;)

Post Reply

Return to “General Topics”

Who is online

Users browsing this forum: No registered users and 2 guests