os/arch/riscv/
timer.rs

1//! RISC-V 架构的定时器实现
2//!
3//! 包含定时器初始化、时间获取和定时器中断设置等功能
4use core::sync::atomic::{AtomicUsize, Ordering};
5
6use crate::{arch::lib::sbi::set_timer, kernel::CLOCK_FREQ};
7use riscv::register::time;
8
9/// 每秒的时钟中断次数
10/// 决定内核每秒想要多少次时钟中断
11pub const TICKS_PER_SEC: usize = 100;
12/// 每秒的毫秒数
13pub const MSEC_PER_SEC: usize = 1000;
14
15/// 记录时钟中断次数
16pub static TIMER_TICKS: AtomicUsize = AtomicUsize::new(0);
17
18/// 获取当前tick数
19#[inline]
20pub fn get_ticks() -> usize {
21    TIMER_TICKS.load(Ordering::Relaxed)
22}
23
24/// 获取当前硬件时钟周期数时间
25#[inline]
26pub fn get_time() -> usize {
27    time::read()
28}
29
30/// 获取当前时间(以毫秒为单位)
31#[inline]
32pub fn get_time_ms() -> usize {
33    (time::read() as u128 * MSEC_PER_SEC as u128 / clock_freq() as u128) as usize
34}
35
36/// 设置定时器中断
37#[inline]
38pub fn set_next_trigger() {
39    let next = get_time() + clock_freq() / TICKS_PER_SEC;
40    set_timer(next);
41}
42
43/// 初始化定时器
44pub fn init() {
45    set_next_trigger();
46    // Safe: 只在内核初始化阶段调用,确保唯一性
47    unsafe { crate::arch::intr::enable_timer_interrupt() };
48}
49
50/// 获取时钟频率
51#[inline]
52pub fn clock_freq() -> usize {
53    // SAFETY: CLOCK_FREQ 在内核初始化阶段被正确设置且之后不会更改
54    unsafe { CLOCK_FREQ }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use crate::{kassert, println, test_case};
61    test_case!(test_set_next_trigger, {
62        let current_time = get_time();
63        set_next_trigger();
64        let next_time = get_time();
65        kassert!(next_time > current_time);
66    });
67
68    // test_case!(test_timer_ticks_increment, {
69    //     crate::arch::trap::init_boot_trap();
70    //     unsafe {
71    //         crate::arch::intr::enable_interrupts();
72    //         crate::arch::intr::enable_timer_interrupt();
73    //     }
74    //     let initial_ticks = TIMER_TICKS.load(Ordering::Relaxed);
75    //     // 模拟等待一段时间以触发定时器中断
76    //     let mut i = 0;
77
78    //     while i < 1000000 {
79    //         core::hint::spin_loop();
80    //         i += 1;
81    //     }
82    //     let later_ticks = TIMER_TICKS.load(Ordering::Relaxed);
83    //     kassert!(later_ticks > initial_ticks);
84    //     unsafe {
85    //         crate::arch::intr::disable_timer_interrupt();
86    //         crate::arch::intr::disable_interrupts();
87    //     }
88    // });
89
90    test_case!(test_get_time, {
91        println!("Testing get_time...");
92        let time = get_time();
93        kassert!(time > 0);
94    });
95
96    test_case!(test_get_time_ms, {
97        println!("Testing get_time_ms...");
98        let time_ms = get_time_ms();
99        kassert!(time_ms > 0);
100    });
101}