Timeline
Timeline
2026-01-05
init
This article introduces the basic concepts, functional features, and application scenarios of the Linux Real-Time Clock (RTC), and discusses in detail the differences between internal RTC and external RTC in terms of definition, advantages, disadvantages, and applicable scenarios. Additionally, it summarizes the RTC peripheral circuit design using the iTOP-RK3568 development board's RX8010 as an example, explaining its I2C interface connection and the power switching mechanism between the main power supply and backup battery.
Linux Driver Notes
| Table of Contents | Links |
|---|---|
| 1. Linux Driver Framework | |
| 2. Linux Driver Loading Logic | |
| 3. Character Device Basics | |
| 4. Concurrency and Competition | |
| 5. Advanced Character Device Progression | |
| 6. Interrupts | |
| 7. Platform Bus | |
| 8. Device Tree | |
| 9. Device Model | |
| 10. Hot Plug | |
| 11. pinctrl Subsystem | |
| 12. gpio Subsystem | |
| 13. Input Subsystem | |
| 14. Single Bus | |
| 15. I2C | |
| 16. SPI | |
| 17. UART | |
| 18. PWM | |
| 19. RTC | |
| 20. Watchdog | |
| 21. CAN | |
| 22. Network Device | |
| 23. ADC | |
| 24. IIO | |
| 25. USB | |
| 26. LCD |
RTC Basics
RTC Introduction
RTC(Real-Time Clock) i.e.Real-Time Clock, is an integrated circuit or module used toprovide precise time information in electronic systems。
Unlike the system’s main processor (CPU),the RTC is primarily responsible for maintaining the system’s real-time date and time,
Main functions of RTC:
- Provide real-time time: RTC can continuously track the current date and time, typically including year, month, day, hour, minute, second, and other information.
- Power-off time retention: RTC is usually equipped with a backup battery (such as a coin cell battery), allowing it to continue running even when the main system loses power, ensuring that time information is not lost.
Application scenarios of RTC:
- Electronic clocks: such as the clock function in devices like computers, phones, and smartwatches.
- Embedded systems: In industrial control and IoT devices, RTC is used to record the time of events.
- Data logging: In scenarios requiring timestamps, RTC provides accurate time information.
- Scheduled tasks: Used to wake up devices or perform specific operations at scheduled times.
Features of RTC:
- Low power consumption: RTC is typically designed for low-power operation, making it suitable for long-term use.
- High precision: Capable of providing relatively accurate time information with small errors.
- Independence: The RTC can operate independently even when the main system is powered off.
Internal RTC and External RTC
Real-time clocks have two common implementation solutions: external RTC and internal RTC.
An external RTC is a dedicated RTC chip independent of the main controller, connected via communication interfaces such as I2C and SPI.。
- Advantages
- It features high precision, providing more accurate time recording.
- The external RTC has an independent power management circuit and can be equipped with a coin cell battery for long-term independent operation, ensuring continuity of time recording even if the main controller loses power or is damaged.
- Disadvantages
- The external RTC has higher costs, requiring additional purchase of chips and related components, while also increasing circuit design complexity and development difficulty, and consuming communication resources of the main controller.
Therefore, external RTC is more suitable for scenarios with high requirements for time accuracy, reliability, and functionality. The iTOP-RK3568 development board integrates an external RTC, using the RX8010 chip, as shown in the following figure:

An internal RTC is a real-time clock module integrated inside the main controller chip.
- Advantages
- It features hardware integration, requiring no additional hardware components, thus offering simple design, low cost, and ease of use.
- Disadvantages
- The internal RTC relies on the main chip’s power supply and typically requires a backup battery to maintain timekeeping after power loss.
Internal RTC Highly susceptible to temperature and voltage fluctuations,Resulting in significant time drift,Reliability is also relatively low 。
Therefore, the internal RTC is more suitable for scenarios with low time precision requirements and cost sensitivity, such as home appliances, simple IoT devices, or systems with low real-time demands.
The power management chip RK809 on the iTOP-RK3568 core board integrates an internal RTC by default, but due to the various disadvantages of the internal RTC mentioned above and the presence of an
external RTC on the baseboard, the internal RTC is not enabled. The internal RTC circuit of the RK809 power management chip is shown below:

Summary
| Category | Internal RTC | External RTC |
|---|---|---|
| Definition | RTC module integrated within the main control chip | Independent dedicated RTC chip connected via I²C/SPI interfaces |
| Features | - Hardware integration - Low-power mode support - Relies on main power supply - Limited accuracy | - Independent operation - High accuracy - Multi-function expansion |
| Advantages | 1. Low cost 2. Simple design 3. Easy to use | 1. High precision 2. Strong independence 3. Feature-rich 4. High reliability |
| Disadvantages | 1. Insufficient precision 2. Lower reliability 3. Lack of independence | 1. Higher cost 2. Complex design 3. Resource-intensive |
| Applicable scenarios | Systems with low time precision requirements, cost sensitivity, and low real-time demands | Scenarios requiring high time precision, long-term independent operation, and additional features |
RK3568 RTC Peripheral

This circuit can be divided into the RTC power supply section and the RTC chip circuit section. According to the RTC chip circuit section, the RX8010 is mounted on I2C5.

The main function of this system is to achieveswitching between main power supply mode and backup battery power supply mode, ensuring that the RTC module can continue to work through the backup battery (VCC3V3_SYS) when the main power (CR1220) is cut off, thereby preventing time information loss. It is divided into the following two cases.
- When the system is operating normally,
VCC3V3_SYSprovides 3.3V power, diode D2 is forward-biased to supply power to the RTC module, while diode D3 is reverse-biased to prevent the main power from charging the battery or draining battery power; - When the system is powered off (
VCC3V3_SYSfails), diode D2 is reverse-biased to prevent battery power from being consumed through the main power circuit, while diode D3 is forward-biased, and theCR1220battery supplies power to the RTC module, ensuring the RTC continues to operate.
RX8010 Driver Analysis and Porting
RTC Subsystem Framework

In the figure above, the RTC subsystem is divided into three layers: user space, device driver layer, and hardware layer. The device driver layer further includes RTC device drivers and the PWM core layer:
User space is the layer where applications run. At this layer, applications interact with the system through different interfaces, such as accessing
/dev/xxxdevice nodes to read and write RTC time, or throughsysfs andprocfile systems to obtain or set hardware status.The middle device driver layer is further divided into RTC device drivers and the RTC core layer.
- The RTC device driver is responsible for operating the specific details of the hardware by directly communicating with the hardware (RTC chip) to achieve hardware control. The device driver is also responsible for exposing the hardware device to the upper-layer system, such as
device(device files) anddriver(drivers)./dev/xxxrefers to the interface files used to operate the device, through which user applications interact with the RTC hardware.driverThe part is a module of the system kernel, responsible for specific hardware control operations.
- The RTC core layer is responsible for managing and coordinating the time management functions of the RTC. It ensures that the system correctly reads and sets the time, while also ensuring that the clock continues to run during power outages.
- The RTC device driver is responsible for operating the specific details of the hardware by directly communicating with the hardware (RTC chip) to achieve hardware control. The device driver is also responsible for exposing the hardware device to the upper-layer system, such as
The RTC hardware layer represents the actual RTC hardware, communicating with the device driver layer through hardware interfaces (such as I2C, SPI, etc.) and providing actual timekeeping functions.
RTC driver source code analysis
Device Tree
1 | //RTC Chip Enable |
Then through the compatible propertyepson,rx8010Find the matching driver file, the specific path of the driver isdrivers/rtc/rtc-rx8010.c, first find the driver’s entry function:
1 | static struct i2c_driver rx8010_driver = { |
module_i2c_driver()
This macro is used to simplify the registration and deregistration process of I2C device drivers, defined ininclude/linux/i2c.hfile, as shown below
1 | /** |
module_driver()
module_drivermacro is also a macro used for simplification, and its corresponding macro definition is as follows
include/linux/device/driver.h
1 | /** |
Finally, substitute the above macro, and expanding it yields the following content:
1 | static int __init rx8010_driver_init(void) |
rx8010_driver_initfunction is called when the module is loaded, and it uses thei2c_add_driverfunction torx8010_driverregister into the kernel.rx8010_driver_exitfunction is called when the module is unloaded, and it uses thei2c_del_driverfunction torx8010_driverunregister from the kernel.
rx8010_probe()
After the compatible match, the probe function is entered. The content of the probe function is as follows:
1 | static int rx8010_probe(struct i2c_client *client, |
In the probe function, arx8010_datastructure variable rx8010 is defined for storing device private data. The structure is defined as follows:
struct rx8010_data
1 | struct rx8010_data { |
i2c_clientis a pointer to the I2C client, used for communication with the RX8010 device, and thertc_devicestructure represents the RTC (Real-Time
Clock) device associated with the RX8010. The structure is defined as follows:
struct rtc_device
1 | struct rtc_device { |
This structure is the core data structure of the RTC device in the Linux kernel, covering all functions and states of the RTC device.
rx8010_init_client()
In the probe function, throughrx8010_init_clientfunction, the RX8010 chip is initialized and configured. Since different RTC chips have different registers, the initialization code also differs.
1 | static int rx8010_init_client(struct i2c_client *client) |
struct rtc_class_ops
1 | if (client->irq > 0) {// Check whether the device provides an interrupt number |
In the probe function, the operation mode of the RTC chip is determined based on whether the device provides an interrupt number. However, since interrupts are not used in either the hardware connection or the device tree configuration, the second condition is entered, which isrtc_ops = &rx8010_rtc_ops_default;
1 | static const struct rtc_class_ops rx8010_rtc_ops_default = { |
rx8010_rtc_ops_defaultProvides a set of default operation function interfaces for the RX8010 real-time clock chip, including a function pointer to read the current time, a function pointer to set the current time, and ioctl external control functions
devm_rtc_device_register()
In the probe function, usedevm_rtc_device_registerfunction to register the RTC device, which is in thedrivers/rtc/class.cfile, and the specific content of the function is as follows:
1 | /** |
__rtc_register_device()
1 | int __rtc_register_device(struct module *owner, struct rtc_device *rtc) |
The main function of this function is to register an RTC device into the RTC subsystem of the Linux kernel. It completes a series of initialization and resource allocation tasks, enabling the kernel to interact with the RTC device through standard interfaces.
The key point is calling thecdev_device_addfunction, which registers the character device and device structure of the RTC device into the kernel, making the RTC device officially part of the kernel and available for use by user space or other kernel modules.
Then there is thertc_proc_add_device, which adds the information of the RTC device to the proc subsystem for debugging and monitoring.
Porting the RX8010 driver

It can be confirmed that the RX8010 is mounted on I2C5, so it is necessary to add an rx8010 node under the i2c5 node in the device tree. The added content is as follows:
1 | &i2c5 { |
The reg attribute indicates that the address of RX8010 is 0x32. This address can be obtained from the RX8010 datasheet, as shown below:

There are a total of 8 bits of data here, because during the actual data transmission process,the first byte sent by the master device contains the slave device address and the read/write bit, where the slave device address occupies the high 7 bits of the byte (bit 7 to bit 1). Therefore, from the figure above, the address of RX8010 is 0110010, which converts to 0x32.
Then go to the root directory of the Linux kernel source code and use menuconfig to enable the RX8010 driver.
1 | Device Drivers |
Additionally, ensure that the internal RTC of the RK power management chip is not selected, to make sure there are no two RTC devices in the system.
1 | Device Drivers |
Time-Related Commands
date Command
date is a very powerful command-line tool in Linux systems, used to display or set the system’s date and time. It can not only view the current system time but also set the system time, format date and time output, parse time strings, and perform time calculations.
- Display Current Date and Time
Running the date command directly will display the current system date and time in the default local time format, as shown below:
1 | $ date |
CST indicates the time zone (China Standard Time)
- Set System Time
The command format for setting the system time using the date command is as follows:
1 | date [MMDDhhmm[[CC]YY][.ss]] |
For example, to set the system time to January 20, 2025, 14:23:45:
1 | date 012014232025.45 |
- Formatted Output
The date command supports customizing the output date and time format using format strings. By adding a + and a format string after the date command, you can specify the output format.
| Format Specifier | Description | Example |
|---|---|---|
%Y | Year (four digits) | 2023 |
%m | Month (two digits) | 10 |
%d | Day (two digits) | 30 |
%H | Hour (24-hour format, two digits) | 14 |
%I | Hour (12-hour format, two digits) | 02 |
%M | Minute (two digits) | 23 |
%S | Second (two digits) | 45 |
%A | Day of week (full name) | Monday |
%a | Day of week (abbreviated name) | Mon |
%B | Month (full name) | October |
%b | Month (abbreviated name) | Oct |
%p | AM/PM | PM |
%Z | Time zone | CST |
For example, format asYYYY-MM-DD HH:MM:SS, and output the current time:
1 | date "+%Y-%m-%d %H:%M:%S" |
hwclock command
hwclock is used in Linux systems toManage hardware clockcommand-line tool. It includes viewing, setting, and synchronizing the hardware clock with the system clock.
- View hardware clock
Running the hwclock command directly displays the current hardware clock time.
1 | $ sudo hwclock |
The hwclock command displays the hardware clock time. The hardware clock typically stores UTC time by default. UTC is the global standard time, defined based on atomic clocks for precision, and is unaffected by variations in Earth’s rotation.
UTC is the global time reference and does not belong to any time zone, hence it is also known as Coordinated Universal Time.
The date command displays the system clock time, which adjusts according to the operating system’s time zone settings.
The printed time zone above is CST, which is China Standard Time, so the date command displays UTC+8. Therefore, the system clock and hardware clock use different time standards, resulting in a time difference between them. Assuming you are in China (UTC+8), the time difference is exactly 8 hours.
- Synchronize hardware clock with system clock
hwclock -sSynchronize system clock to hardware clockhwclock -wSynchronize hardware clock to system clock
Every time the system powers on and boots, the hardware time from the RTC is synchronized to the system time. The specific implementation is in the kerneldrivers/rtc/class.cfile’srtc_hctosysfunction. The specific content of this function is as follows:
1 |
|
Through thertc_read_timefunction, read the time stored in the RTC hardware, then through thedo_settimeofday64function, set the converted timestamp to the system clock.
RTC Application Programming
ioctlMacro Definition Analysis
RTC_RD_TIME
1 |
_IOR(type, nr, data_type): IndicatesReading data from the kernel to user space。'p': Magic number, used to distinguish different devicesioctlcommand (RTC is fixed to'p')。0x09: Command number.struct rtc_time: Expected data type.
Function:Read the current time from RTC hardware(Note: Not the system time!)
RTC_SET_TIME
1 |
_IOW(type, nr, data_type): Indicateswriting data from user space to the kernel。- Other parameters are the same as above.
Function:Write the user-specified time to RTC hardware(Usually requires root privileges).
struct rtc_timestructure
This is the standard time structure defined by the Linux kernel (located in<linux/rtc.h>), with the C standard library’sstruct tmalmost identical, butnot guaranteed to be fully compatible(especially when cross-platform).
| Field | Range | Description | ⚠️ Note |
|---|---|---|---|
tm_sec | 0–59 | Seconds | — |
tm_min | 0–59 | Minutes | — |
tm_hour | 0–23 | Hours (24-hour) | — |
tm_mday | 1–31 | Day of month (starting from 1) | Not 0-based! |
tm_mon | 0–11 | Month (0=Jan) | Error-prone! |
tm_year | Year - 1900 | e.g., 2023 →123 | Must subtract 1900! |
tm_wday | 0–6 | Day of week (0=Sun) | Driver usually auto-calculates |
tm_yday | 0–365 | Day of year | Driver usually auto-calculates |
tm_isdst | Usually 0 | Daylight saving flag | RTC hardware generally does not support |
Key Pitfalls:
- Set February 15, 2023 →
.tm_year = 123,.tm_mon = 1- Add back when printing:
tm_year + 1900,tm_mon + 1
Example
1 |
|
Read: Usually readable by normal users (depends on udev rules).
Write (
RTC_SET_TIME):requires root privilegesorCAP_SYS_TIMEcapability.

