ax-arm-pl031
路径:
drivers/rtc/arm_pl031类型:库 crate 分层:组件层 / 可复用基础组件 版本:0.2.1文档依据:Cargo.toml、README.md、src/lib.rs、src/chrono.rs
ax-arm-pl031 是 ARM PrimeCell PL031 RTC 的薄封装驱动。它不负责设备树、页表映射、GIC 接线或平台时间策略,而是把一组固定布局的 MMIO 寄存器包装成 Rtc 句柄和少量 Unix 时间戳读写接口,供更高层平台代码接入墙钟语义。
架构设计
设计定位
这个 crate 的目标非常克制:
- 它只负责 PL031 寄存器级访问。
- 它对外暴露的是“秒级 Unix 时间戳”“匹配寄存器”“中断状态”这些最基础能力。
- 它并不试图实现完整 RTC 子系统,更不会自己决定 wall clock 与 monotonic clock 的组合策略。
因此,ax-arm-pl031 更适合被视为“平台时间源的寄存器级基础组件”,而不是“通用时钟框架”。
模块结构
src/lib.rs:核心实现。定义寄存器布局Registers、设备句柄Rtc以及所有 MMIO 读写方法。src/chrono.rs:在chronofeature 下提供DateTime<Utc>风格的便捷封装。
1.3 关键数据结构与寄存器语义
Registers:按#[repr(C, align(4))]定义的 PL031 MMIO 寄存器块。Rtc:对外唯一核心对象,内部只持有一个NonNull<Registers>指针。
Rtc 实际操作的主要寄存器包括:
DR:当前 RTC 值。MR:匹配寄存器。LR:加载寄存器。IMSC:中断屏蔽/使能寄存器。RIS:原始中断状态。MIS:屏蔽后的中断状态。ICR:中断清除寄存器。
需要特别注意的是:结构体中虽然保留了 CR 字段,但当前公开 API 并未直接暴露对 CR 的操作。这意味着该 crate 假设硬件或更早的初始化阶段已经把设备置于可工作的状态。
1.4 在仓库中的实际使用主线
在本仓库里,ax-arm-pl031 的真实接入路径不在它自己内部,而在动态平台驱动注册和平台时间路径中:
也就是说,ax-arm-pl031 在平台栈中的主要角色不是“持续提供复杂时钟服务”,而是在极早期读一次硬件墙钟,建立单调时间到真实墙钟的偏移量。
1.5 安全与平台假设
Rtc::new(base) 的 unsafe 前提非常明确:
- 传入地址必须真的是 PL031 寄存器块。
- 该地址必须已经映射为正确的设备内存属性。
- 访问者需要自己保证没有错误别名和未定义并发访问。
此外,还存在几个隐含假设:
- 时间 API 以
u32秒为单位,因此天然带有 32 位时间戳范围限制。 chrono路径里使用Utc.timestamp_opt(...).unwrap(),在极端异常值下可能 panic。- 若平台没有调用
pl031::init_early(),那么更高层墙钟偏移可能保持为 0。
核心功能
功能概览
- 读取当前 Unix 时间戳。
- 设置当前 Unix 时间戳。
- 设置匹配时间戳。
- 查询匹配状态和中断状态。
- 使能、关闭和清除 RTC 中断。
- 在
chronofeature 下提供DateTime<Utc>风格接口。
使用场景
Rtc::new(base):构造 MMIO 句柄。get_unix_timestamp()/set_unix_timestamp():最核心的时间读写 API。set_match_timestamp():设置匹配中断阈值。matched()/interrupt_pending():查询状态。enable_interrupt()/clear_interrupt():中断控制。get_time()/set_time()/set_match():chrono风格便捷包装。
使用方式
最常见的使用方式是平台代码在知道 MMIO 基址后构造 Rtc:
let rtc = unsafe { ax_arm_pl031::Rtc::new(mmio_ptr) };
let secs = rtc.get_unix_timestamp();
let _ = secs;
在本仓库中,更高层通常不会长期持有 Rtc 做复杂操作,而是读取一次时间戳,再转成墙钟偏移。
依赖关系
直接依赖
- 默认情况下几乎只依赖
core。 chrono是可选依赖,用于提供更方便的时间表示层。
主要消费者
ax-driver动态平台 RTC probe:在动态平台设备发现后注册 PL031 RTC 能力。
3.3 间接消费者
- 通过
axplat-dyn/ax-hal共享这条平台路径的 ArceOS 栈。 - StarryOS、Axvisor 的依赖图中可能间接出现该 crate,但是否实际启用取决于具体平台包与 feature 组合。