OK3568 RTC 驱动适配与 Linux 系统时间管理总结

OK3568 RTC 驱动适配与 Linux 系统时间管理总结

文章目录

  • [OK3568 RTC 驱动适配与 Linux 系统时间管理总结](#OK3568 RTC 驱动适配与 Linux 系统时间管理总结)
    • 一、背景
    • 二、适配步骤
      • [2.1 I2C 总线确认](#2.1 I2C 总线确认)
      • [2.2 驱动文件确认](#2.2 驱动文件确认)
      • [2.3 修改设备树](#2.3 修改设备树)
      • [2.4 内核配置开启 RX8010 驱动](#2.4 内核配置开启 RX8010 驱动)
      • [2.5 烧写验证](#2.5 烧写验证)
    • [三、RTC 与系统时间的关系(核心知识点)](#三、RTC 与系统时间的关系(核心知识点))
      • [3.1 两个时钟的区别](#3.1 两个时钟的区别)
      • [3.2 上电同步:hctosys](#3.2 上电同步:hctosys)
      • [3.3 运行期间的同步命令](#3.3 运行期间的同步命令)
      • [3.4 时区注意](#3.4 时区注意)
    • 四、调试过程与问题解决
      • [4.1 问题一:Frequency stop 告警](#4.1 问题一:Frequency stop 告警)
    • [五、BMS 场景的时间管理方案](#五、BMS 场景的时间管理方案)
    • 六、总结

一、背景

硬件平台 RTC 芯片
FCU2601 核心板 RX8010SJ(EPSON)
OK3568 开发板 PCF8563(NXP)
BCU3.0 产品 RX8010SJ

BCU3.0 使用的核心板与 OK3568 开发板一致(都是飞凌的 OK3568-C),但 RTC 芯片从 PCF8563 换成了 RX8010SJ,因此需要将软件从 PCF8563 适配到 RX8010SJ。


二、适配步骤

2.1 I2C 总线确认

查看 BCU3.0 原理图与 OK3568 原理图,两颗 RTC 芯片都挂在 RK3568 的 I2C3 总线上:

芯片 I2C 地址
RX8010 0x32
PCF8563 0x51

I2C 总线驱动不需要修改,只需调整设备树。

2.2 驱动文件确认

OK3568 SDK 内核源码中已包含两套 RTC 驱动:

bash 复制代码
ls kernel/drivers/rtc/rtc-rx8010.c
ls kernel/drivers/rtc/rtc-pcf8563.c

不需要自己编写驱动,关键是要在内核配置中启用 RX8010 驱动

2.3 修改设备树

文件位置:

复制代码
OK3568_Linux_fs/kernel/arch/arm64/boot/dts/rockchip/OK3568-C-common.dtsi

修改前(原代码):

dts 复制代码
&i2c3 {
    status = "okay";

    rx8010: rx8010@32 {
        compatible = "epson,rx8010";
        reg = <0x32>;
    };

    pcf8563: pcf8563@51 {
        compatible = "nxp,pcf8563";
        reg = <0x51>;
        #clock-cells = <0>;
    };
};

修改后:

dts 复制代码
&i2c3 {
    status = "okay";

    rx8010: rx8010@32 {
        compatible = "epson,rx8010";
        reg = <0x32>;
        status = "okay";        /* 启用 RX8010 */
    };

    pcf8563: pcf8563@51 {
        compatible = "nxp,pcf8563";
        reg = <0x51>;
        status = "disabled";    /* 禁用 PCF8563 */
    };
};

关键变化:RX8010 加 status = "okay",PCF8563 加 status = "disabled"。确保同一 I2C 总线上只有一颗 RTC 芯片被使能。

2.4 内核配置开启 RX8010 驱动

这是整个适配中最容易被忽略的一步。默认的 OK3568 板级 defconfig 中 RX8010 驱动未使能

bash 复制代码
zcat /proc/config.gz | grep RX8010
# 输出:# CONFIG_RTC_DRV_RX8010 is not set

需要修改板级 defconfig(注意:直接 make menuconfig.config 无效,因为飞凌的 build.sh kernel 每次会用 defconfig 覆盖 .config):

bash 复制代码
cd /home/forlinx/3568/OK3568-linux-source/kernel/arch/arm64/configs/
vim OK3568-C-linux_defconfig

在文件末尾添加:

复制代码
CONFIG_RTC_DRV_RX8010=y

保存后重新编译内核:

bash 复制代码
cd /home/forlinx/3568/OK3568-linux-source
./build.sh kernel

编译完成后验证:

bash 复制代码
grep RX8010 kernel/.config
# 预期输出:CONFIG_RTC_DRV_RX8010=y

2.5 烧写验证

将新生成的 boot.img 烧写到开发板 boot 分区,重启后验证:

bash 复制代码
# 1. 确认驱动已编译进内核
zcat /proc/config.gz | grep RX8010
# → CONFIG_RTC_DRV_RX8010=y

# 2. 确认驱动注册成功
dmesg | grep -i rtc
# → rtc-rx8010 3-0032: rtc core: registered rx8010 as rtc0
# → rtc-rx8010 3-0032: setting system clock to 2026-06-05 02:35:21 UTC

# 3. 确认设备节点存在
ls /dev/rtc*
# → /dev/rtc  /dev/rtc0

三、RTC 与系统时间的关系(核心知识点)

3.1 两个时钟的区别

复制代码
┌─────────────────────────────────────────┐
│              Linux 系统                   │
│                                          │
│  系统时间 (Software Clock)               │
│  · 内核维护的软件计数器                   │
│  · date / timedatectl 查看               │
│  · 纳秒级精度                             │
│  · 基于 CPU 定时器中断累加                │
│  · ❌ 断电丢失,重启归零                  │
│                                          │
│          ↕  hwclock 命令                  │
│                                          │
│  RTC 硬件时钟 (Hardware Clock)            │
│  · I2C 芯片 RX8010 内部计时               │
│  · hwclock -r 查看                        │
│  · 秒级精度                               │
│  · 32.768kHz 晶振                         │
│  · ✅ Vbat 供电 → 断电保持                │
└─────────────────────────────────────────┘
系统时间 RTC 硬件时钟
存储位置 内核内存变量 I2C RTC 芯片寄存器
断电后 丢失 保持
精度 纳秒级 秒级
读取命令 date hwclock -r
写入命令 date -s hwclock -w

3.2 上电同步:hctosys

Linux 内核启动时,如果开启了 CONFIG_RTC_HCTOSYS=y,会自动从 RTC 读取时间并设置为系统时间:

bash 复制代码
zcat /proc/config.gz | grep HCTOSYS
# → CONFIG_RTC_HCTOSYS=y
# → CONFIG_RTC_HCTOSYS_DEVICE="rtc0"

dmesg 日志中能看到:

复制代码
rtc-rx8010 3-0032: setting system clock to 2026-06-05 02:35:21 UTC

这个过程是内核自动完成的,不需要用户编写任何代码。

3.3 运行期间的同步命令

场景 命令 说明
查看系统时间 date 本地时区显示
查看 RTC 时间 sudo hwclock -r 读硬件时钟
RTC → 系统 sudo hwclock -s hctosys 手动版
系统 → RTC sudo hwclock -w systohc
查看完整信息 timedatectl status 含时区、NTP 状态
设置系统时间 sudo date -s "2026-06-05 15:30:00" 临时校准

3.4 时区注意

RTC 硬件时钟通常存储 UTC 时间 (内核驱动默认行为),系统时间显示为本地时间+08:00 北京时区)。

dmesg 里看到的是 UTC:02:35:21 UTCdate 显示是 10:35:21 CST,差了 8 小时是正常的。

应用程序拿时间用 time() / gettimeofday() 取系统时间即可,时区转换由系统处理。


四、调试过程与问题解决

4.1 问题一:Frequency stop 告警

首次上电后 dmesg 出现:

复制代码
rtc-rx8010 3-0032: Frequency stop was detected
rtc-rx8010 3-0032: hctosys: unable to read the hardware clock

原因:RX8010 上电后检测到内部振荡器曾停振(XST 标志位),驱动拒绝读取时钟。这是新芯片首次上电、或者 Vbat 备份电源掉过电的典型现象。

解决 :先用 hwclock -w 写入一次系统时间,驱动写入操作会清除 XST 标志:

bash 复制代码
# 先随便设一个系统时间(或从网络获取)
sudo date -s "2026-06-05 15:30:00"

# 写入RTC(同时清除XST标志)
sudo hwclock -w -f /dev/rtc0

# 验证读数正常
sudo hwclock -r -f /dev/rtc0

写入成功后,Frequency stop 告警消失,hctosys 恢复正常。

五、BMS 场景的时间管理方案

BCU3.0 常规运行不联网,没有 NTP 时间源。时间同步闭环如下:

复制代码
上电启动
  └── 内核 hctosys:RTC → 系统时间(自动,零代码)
       │
运行期间(104 主站对时)
  └── 收到时钟同步指令
       ├── settimeofday() 校准系统时间
       └── hwclock -w 写入 RTC
       │
下次断电再上电
  └── RTC 保持正确时间 → hctosys → 系统时间恢复
环节 负责方 是否需要自己写代码
上电 RTC→系统 内核 CONFIG_RTC_HCTOSYS=y 不需要
运行中读取时间 time() / gettimeofday() 一行调用
时间校准 104 主站下发对时指令 需实现 handler
校准后写回 RTC hwclock -w 一行命令
故障录波时间戳 直接从系统时间取 不需要

六、总结

RTC 驱动的适配本质上是三件事:

  1. 设备树------让内核知道 I2C3 上挂了什么芯片
  2. 内核配置 ------把对应驱动编译进去(CONFIG_RTC_DRV_RX8010=y
  3. 理解 RTC 与系统时间的关系------启动自动同步(hctosys)、运行中读写(hwclock)、断电保持(备份电池)

整个过程中不需要自己写一行 RTC 驱动代码,内核社区已经做好了全部工作。你的应用程序只需要 time() 取系统时间即可,RTC 对上层透明。


参考资料


最后更新:2026-06-05

相关推荐
戴为沐6 小时前
Linux内存扩容指南
linux
zylyehuo16 小时前
Linux 彻底且安全地删除文件
linux
用户805533698031 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297911 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
Web3探索者3 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo3 天前
Linux系统中网线与USB网络共享冲突
linux
Sokach10154 天前
Linux Shell 脚本从零到能用:一个新手的一天学习总结
linux
AlfredZhao5 天前
Docker 容器时区不对,`timedatectl` 不存在怎么办?
linux·timezone
zzzzzz3106 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
XIAOHEZIcode6 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏