The system clock is managed by the OS, and it is the tick or heartbeat of the system. The OS keeps track of the system clock while executing. The system clock is the primary clock and operates only when the OS is running; it stops when the system is powered off. Another clock is the RTC clock which is an independent clock and is generally powered by the backup battery or power source. It keeps running even if the system is not on. When the system is powered on, the system clock gets the initial time from the RTC clock while booting. This is how the system maintains the real-time status of the day. Time persists even when the system is not on.
Let us discuss the RTC clock only. The RTC clock can be embedded on the SOC or it can be small mounting chip interfaced with the CPU over I2C bus. There are many I2C RTC clock devices available.
Let us explore if the user wants to enable the RTC in the system. To enable the new RTC chip on the system, a Linux driver for the RTC module is required. These drivers will be provided by RTC manufacturers. The only example of an RTC module that I can think of is DS1339 from Maxim Integrated. Let us say that your system designer has added this chip to your system. Currently, your Linux will not be aware of the RTC device. But if the i2c-tools are available on the system, then you can probably see the new i2c slave device when you execute “i2cdetect -y 1”. This device will list all the slave devices on the i2c bus number 1. Next comes the enablement of the RTC driver in Linux. The RTC drive for the DS1339 is already available. rtc-ds1307.c is the Linux driver for RTC DS1339 and can be looked into in the directory (drivers/rtc) of the kernel source. One should enable the kernel config(CONFIG_RTC_DRV_DS1307) to enable the driver for this RTC device in Linux.
In addition to the kernel config, one should also make changes in the device tree, which will create an instance of the I2C device. This instance will be probed based on the compatible string defined during the previous step.
The device will probe the driver based on the compatible string. Once the driver and device successfully bind, device node will be created for the userspace to access the RTC. /dev/rtc0 will be the device interface for userspace access.
To access the RTC from userspace, “hwclock” utility can be used.
If we check the hwclock help, we will see the following options:
Usage: hwclock [-r|--show] [-s|--hctosys] [-w|--systohc] [-t|--systz] [-l|--localtime] [-u|--utc] [-f|--rtc FILE]
-r --> To display clock time of hardware
-s --> Take time form hardware clock and put to system clock
-w --> Take time form system clock and put to hardware clock
-t --> Put kernel timezone
-u --> Take it as hardware clock is placed in UTC
-l --> Take it as hardware clock is placed in local time
-f --> FILE Use specified device (e.g. /dev/rtc2)
These are the minimal options offered by this command.
We will only discuss some of these options, as they are used generally.
This option is used to display the output of the RTC clock.
Below is the output from the system with me:
Tue Aug 15 18:26:36 2023 0.000000 seconds
This option is used to set/update the time in the RTC clock. The next read operation will give us the updated time if the time update was successful. Also, the -w option will not produce any errors. A silent execution of -w option means the setting of time is successful. The point to note here is that the -w option will copy the system time to the RTC clock. So if we want to update the RTC clock, first we should update the system clock time. This can be done with the date command and then later executed with hwclock -w to update the RTC time. This way, RTC time will be updated.
Let us have a look at the time of the system. Execute the data and hwclock command. On my system, I am seeing both the commands at the same time.
Tue Aug 15 18:33:16 UTC 2023
[$]$ hwclock -r
Tue Aug 15 18:33:17 2023 0.000000 seconds
Let us try changing the system time with the date command as below. The Time and Data have been changed to Nov 7, 2023.
Tue Nov 7 07:08:10 UTC 2023
Tue Nov 7 07:08:22 UTC 2023
Now, let us check the output of both the clocks–the RTC and system clock.
Tue Nov 7 07:09:51 UTC 2023
[$]$ hwclock -r
Tue Aug 15 18:37:42 2023 0.000000 seconds
The system clock has been changed, and it is now set to Nov 7, 2023, while the RTC clock is still running at the older time, as we have seen in the earlier outputs.
Now, if we just execute the “hwclock -w”, our RTC clock time will be updated from the system time. Let us confirm this on our system.
Tue Aug 15 18:40:11 2023 0.000000 seconds
Tue Nov 7 07:12:25 UTC 2023
[$]$ hwclock -w
[$]$ hwclock -r
Tue Nov 7 07:12:34 2023 0.000000 seconds
Tue Nov 7 07:12:43 UTC 2023
As we can see in the above example, once we have used the -w option, the system time and the RTC time is same. RTC time got updated with the same values as of system time.
With all the above discussion, our understanding is that we can change the system clock independently with respect to hardware clock (RTC). Once both clocks are running at different times, how we can sync them? We have already seen the case where we can copy the system time to the RTC. But how do we set the RTC time to the system clock? For this purpose, the hwclock command provides the option: -s or –hctosys. When the hwlock command is executed with the -s/–hctosys option, the time from hardware clock (RTC) is copied to the system clock.
We discussed the RTC representation in Linux. We have seen the RTC enablement in Linux, which requires kernel config and device tree enablement. We also explored the RTC manipulation from the user space command using the hwclock command provided on the Linux system. We discussed many example command operations. With all this discussion, you should have the fair idea of RTC in Linux.