2. Cvitek RTC Operation Guide¶
2.1. Module Introduction¶
RTC (real-time clock) is an independently powered module in the processor that provides time to Linux. Because the RTC is battery-powered, it keeps time while the processor is powered off or sleeping. The Linux kernel uses the RTC to maintain the time and date, and it can also serve as an alarm to wake the kernel from sleep.
Applications can use the periodic interrupts provided by the RTC for periodic tasks.
2.1.1. Counter Clock Frequency¶
The RTC counter uses a 32.768 kHz clock and a 32-bit up-counter to count seconds. The maximum count duration is:
2^32 seconds = 49,710 days = 136 years
2.2. Preparation¶
2.2.1. Using the RTC (Default)¶
Use the U-Boot and kernel released with the SDK; no DTS modification is required.
Device node:
/dev/rtc0.
2.2.2. Removing the RTC¶
To disable the RTC at board level, use delete-node delete the RTC node.
In this SDK, the RTC node is named rtc (in cv184x_base.dtsi / cv1835_asic.dtsi is defined there; the deletion example is as follows:
/ {
/delete-node/ rtc;
};
If the node is named cvitek-rtc@3005000, use:
/delete-node/ cvitek-rtc@3005000;
The following is another node-deletion example in the same file (for reference only):
/delete-node/ i2s@04120000;
/delete-node/ sound_ext1;
/delete-node/ sound_ext2;
/delete-node/ sound_PDM;
/delete-node/ rtc; /* 删除 RTC */
aliases {
/delete-property/ ethernet1;
};
2.3. Application-layer Usage¶
2.3.1. Device Node and Header Files¶
Device node:
/dev/rtc0Header files:
#include <linux/rtc.h>,#include <sys/ioctl.h>
2.3.2. Common ioctl Commands¶
Command |
Description |
|---|---|
RTC_RD_TIME |
Read the current time |
RTC_SET_TIME |
Set the current time |
RTC_ALM_READ |
Read the alarm time |
RTC_ALM_SET |
Set the alarm time |
RTC_AIE_ON |
Enable the alarm interrupt |
RTC_AIE_OFF |
Disable the alarm interrupt |
RTC_UIE_ON |
Enable the update interrupt |
RTC_UIE_OFF |
Disable the update interrupt |
RTC_PIE_ON |
Enable the periodic interrupt |
RTC_PIE_OFF |
Disable the periodic interrupt |
RTC_IRQP_SET |
Set the periodic interrupt frequency |
2.3.3. rtc_time Structure¶
struct rtc_time {
int tm_sec; /* 秒 [0,59] */
int tm_min; /* 分 [0,59] */
int tm_hour; /* 时 [0,23] */
int tm_mday; /* 日 [1,31] */
int tm_mon; /* 月 [0,11],0=1月 */
int tm_year; /* 年,实际年 = tm_year + 1900 */
int tm_wday; /* 星期几 [0,6],0=周日,1=周一 */
int tm_yday; /* 一年中第几天 [0,365],0=1月1日 */
int tm_isdst; /* 夏令时:1=是,0=否 */
};
Note:
tm_mon: 0 means 1 month, 11 means 12 month.tm_year: storeis"yearcopy − 1900", if 2025 yearfill 125.tm_wday: 0=Sunday, 1=weekone, according tothisanalogy.tm_yday: 0=1month1day, 1=1month2day.
2.4. Example Code¶
2.4.1. User-space Operation Example (rtc_example.c) ¶
theshowexamplewill"readtime / settime / setalarm"entirecombinedisoneprogram, throughparameterselectspecificoperation.
Build
arm-none-linux-uclibcgnueabihf-gcc -o rtc_example rtc_example.c -static
Run
./rtc_example [read|set|alarm]
read: readandprintcurrent RTC time.set: will RTC setisshowexampletime (2025-03-18 12:00:00) , andprintsetaftertime.alarm: willalarmsetiscurrenttime + 5 seconds, andenablealarminterrupt (part RTC maynot supportedalarminterrupt, willreturnerror) .
/*
* Cvitek RTC 使用示例:读取时间、设置时间、设置闹钟
* 编译: arm-none-linux-uclibcgnueabihf-gcc -o rtc_example rtc_example.c -static
* 运行: ./rtc_example [read|set|alarm]
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define RTC_DEV "/dev/rtc0"
static void print_rtc_time(const struct rtc_time *t)
{
printf("RTC 时间: %04d-%02d-%02d %02d:%02d:%02d 星期%d\n",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, t->tm_wday);
}
/* 读取并打印当前 RTC 时间 */
static int do_read(int fd)
{
struct rtc_time rtc_tm;
if (ioctl(fd, RTC_RD_TIME, &rtc_tm) < 0) {
perror("RTC_RD_TIME");
return -1;
}
print_rtc_time(&rtc_tm);
return 0;
}
/* 设置 RTC 时间(示例:2025-03-18 12:00:00) */
static int do_set(int fd)
{
struct rtc_time rtc_tm = {
.tm_sec = 0,
.tm_min = 0,
.tm_hour = 12,
.tm_mday = 18,
.tm_mon = 2, /* 3 月 */
.tm_year = 125, /* 2025 */
.tm_wday = 2,
.tm_isdst = 0
};
if (ioctl(fd, RTC_SET_TIME, &rtc_tm) < 0) {
perror("RTC_SET_TIME");
return -1;
}
printf("已设置 RTC,当前为: ");
return do_read(fd);
}
/* 设置闹钟为当前时间 + 5 秒,并开启闹钟中断 */
static int do_alarm(int fd)
{
struct rtc_time rtc_tm;
if (ioctl(fd, RTC_RD_TIME, &rtc_tm) < 0) {
perror("RTC_RD_TIME");
return -1;
}
rtc_tm.tm_sec += 5;
if (rtc_tm.tm_sec >= 60) {
rtc_tm.tm_sec %= 60;
rtc_tm.tm_min++;
}
if (rtc_tm.tm_min >= 60) {
rtc_tm.tm_min = 0;
rtc_tm.tm_hour++;
}
if (rtc_tm.tm_hour >= 24)
rtc_tm.tm_hour = 0;
if (ioctl(fd, RTC_ALM_SET, &rtc_tm) < 0) {
if (errno == EINVAL)
fprintf(stderr, "此 RTC 不支持闹钟中断\n");
else
perror("RTC_ALM_SET");
return -1;
}
ioctl(fd, RTC_AIE_ON, 0);
printf("闹钟已设为 5 秒后,已开启闹钟中断\n");
return 0;
}
int main(int argc, char **argv)
{
const char *cmd = (argc > 1) ? argv[1] : "read";
int fd = open(RTC_DEV, O_RDONLY);
if (fd < 0) {
perror("open " RTC_DEV);
return 1;
}
if (strcmp(cmd, "read") == 0)
do_read(fd);
else if (strcmp(cmd, "set") == 0)
do_set(fd);
else if (strcmp(cmd, "alarm") == 0)
do_alarm(fd);
else {
fprintf(stderr, "用法: %s [read|set|alarm]\n", argv[0]);
close(fd);
return 1;
}
close(fd);
return 0;
}
2.5. Summary¶
operation |
Procedure |
|---|---|
Using the RTC |
Keep the node and operate directly on |
Removing the RTC |
Add |
Read time |
|
Set time |
populate |
Set alarm |
populatetimeafter |
2.6. Timed Reboot by RTC Interrupt (Soft Reboot)¶
A soft reboot does not remove power or trip the power supply; it only makes the CPU/SoC run the boot process again while power remains on. Triggering it when an RTC alarm expires enables a timed soft reboot.
2.6.1. Procedure¶
Find
auto_restart_afternode path on the device:
find /sys/devices/ -name auto_restart_after
Write a number of seconds to this node to trigger a soft reboot after the specified delay. The example below reboots after 30 seconds; replace the path with the actual node returned by the previous
findobtaintoactualsectionpoint (usuallyshapeif/sys/devices/platform/5026000.rtc/auto_restart_after) :
echo 30 > /sys/devices/platform/5026000.rtc/auto_restart_after
2.6.2. Flow from the RTC Alarm to SoC Reset¶
Set RTC alarm: userthrough sysfs writeattribute
auto_restart_after, for examplecommandecho 30, meansabout 30 secondsafterreboot. driverread RTC currentsecondsnumber, will"currentsecondsnumber + setsecondsnumber"Write RTC alarmregisterandenablealarm.RTC alarminterrupt: topointafter RTC hardwarecomparerelativelysecondscountwithalarmtime, pullhighinterrupt. inkernel RTC driverininterruptprocessingfunctioninclearinterrupt, through
rtc_update_irq()common notificationuserstate/dev/rtc0, andraisesubmitonedelayworkingitem.workingqueuecolumnintriggersendreboot: inworkingfunctionin, If thisbeforealreadythrough
auto_restart_aftersetsetwhenreboot, thencallorderly_reboot(); If timeoutunusedrebootthenthencallkernel_restart(NULL).orderly_reboot: firsttryexecute
/sbin/reboot, giveuserstatedoreceivetail (sync, scriptthisetc.) ; If executefailedthen directlyconnectcallkernel_restart(NULL).kernel_restart: enterrebootpreparationstepsegment (common notificationchain, device shutdown, migratetoreboot CPU, systemcoredisable, inkernellog dump) , Finally, callarchitecturerelated
machine_restart().machine_restart (ARM64) : disableinterrupt, stopstopitsit CPU, thencall
do_kernel_restart().do_kernel_restart: callthehasthrough
register_restart_handler()registerrebootbackadjust.Cvitek rebootbackadjust: in
cvi-reboot.cinregistercvi_restart_handler()write RTC domainregisterpleaserequestwarmresetbits (RTC_EN_WARM_RST_REQ) , etc.wait forstatusthencompleteafterwrite RTC_CTRL0 triggersend SoC internal warm reset. CPU from BootROM/firmwarere-newboot, complete devicenotpower off, completesoftreboot.
2.6.3. Key Points¶
RTC alarm: provide"topointtriggersend", use RTC currentsecondsnumber + N secondsSet alarm, withsystemtimedecouple.
orderly_reboot: firstexecute
/sbin/rebootdouserstatereceivetail, failedthen directlyconnectkernel_restart.kernel_restart: disabledevice, migrate CPU, dump log, thensubmitgivearchitecture
machine_restart.cvi_restart_handler: Cvitek SoC softresetbitsimplement, throughwrite RTC domain WARM_RST_REQ byhardwaredo CPU/SoC warmresetbits, powerkeep powered.