1 use core::fmt::Debug; 2 3 use alloc::{string::String, sync::Arc}; 4 use system_error::SystemError; 5 6 use crate::{ 7 libs::rwlock::RwLock, 8 time::{Instant, PosixTimeSpec, NSEC_PER_SEC}, 9 }; 10 11 use self::sysfs::RtcGeneralDevice; 12 13 use super::base::device::Device; 14 15 pub mod class; 16 pub mod interface; 17 pub mod rtc_cmos; 18 mod sysfs; 19 mod utils; 20 21 /// 全局默认rtc 22 static GLOBAL_DEFAULT_RTC: RwLock<Option<Arc<RtcGeneralDevice>>> = RwLock::new(None); 23 24 /// 获取全局的默认的rtc 25 fn global_default_rtc() -> Option<Arc<RtcGeneralDevice>> { 26 GLOBAL_DEFAULT_RTC.read().clone() 27 } 28 29 /// 注册默认的rtc 30 fn register_default_rtc(general_device: Arc<RtcGeneralDevice>) -> bool { 31 let upg = GLOBAL_DEFAULT_RTC.upgradeable_read(); 32 if let Some(old_dev) = upg.as_ref() { 33 if old_dev.priority() >= general_device.priority() { 34 return false; 35 } 36 } 37 38 let mut write = upg.upgrade(); 39 40 write.replace(general_device); 41 42 return true; 43 } 44 45 /// RTC设备的trait 46 pub trait RtcDevice: Device { 47 fn class_ops(&self) -> &'static dyn RtcClassOps; 48 } 49 50 #[allow(dead_code)] 51 pub trait RtcClassOps: Send + Sync + Debug { 52 fn read_time(&self, dev: &Arc<dyn RtcDevice>) -> Result<RtcTime, SystemError>; 53 fn set_time(&self, dev: &Arc<dyn RtcDevice>, time: &RtcTime) -> Result<(), SystemError>; 54 } 55 56 #[derive(Default, Debug, Clone, Copy)] 57 pub struct RtcTime { 58 /// `second`: 秒,范围从 0 到 59 59 pub second: i32, 60 /// `minute`: 分钟,范围从 0 到 59 61 pub minute: i32, 62 /// `hour`: 小时,范围从 0 到 23 63 pub hour: i32, 64 /// `mday`: 一个月中的第几天,范围从 1 到 31 65 pub mday: i32, 66 /// `month`: 月份,范围从 0 到 11 67 pub month: i32, 68 /// `year`: 年份(相对于1900年) 69 pub year: i32, 70 /// `wday`: 一周中的第几天,范围从 0(周日)到 6(周六) 71 pub wday: i32, 72 /// `yday`: 一年中的第几天,范围从 1 到 366 73 pub yday: i32, 74 /// `isdst`: 表示是否为夏令时,通常如果是夏令时,此值为正,否则为零或负 75 pub isdst: i32, 76 } 77 78 impl RtcTime { 79 /// 返回一个格式化的日期字符串 80 /// 81 /// 例如,如果日期为2021年1月1日,则返回"2021-01-01" 82 pub fn date_string(&self) -> String { 83 format!( 84 "{:04}-{:02}-{:02}", 85 self.year_real(), 86 self.month_real(), 87 self.mday 88 ) 89 } 90 91 /// 返回一个格式化的时间字符串 92 /// 93 /// 例如,如果时间为12:00:00,则返回"12:00:00" 94 pub fn time_string(&self) -> String { 95 format!("{:02}:{:02}:{:02}", self.hour, self.minute, self.second) 96 } 97 98 pub fn valid(&self) -> bool { 99 !(self.year < 70 100 || self.year > (i32::MAX - 1900) 101 || self.month >= 12 102 || self.month < 0 103 || self.mday < 1 104 || self.mday > self.month_days() 105 || self.hour >= 24 106 || self.hour < 0 107 || self.minute >= 60 108 || self.minute < 0 109 || self.second >= 60 110 || self.second < 0) 111 } 112 113 /// 获取当月有多少天 114 pub fn month_days(&self) -> i32 { 115 let days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 116 let month = self.month as usize; 117 let mut days = days_in_month[month]; 118 119 if month == 1 && self.is_leap_year() { 120 days += 1; 121 } 122 123 days 124 } 125 126 /// 判断当前是否为闰年 127 pub fn is_leap_year(&self) -> bool { 128 let year = self.year + 1900; 129 (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 130 } 131 132 pub fn year_real(&self) -> i32 { 133 self.year + 1900 134 } 135 136 pub fn month_real(&self) -> i32 { 137 self.month + 1 138 } 139 } 140 141 impl From<RtcTime> for PosixTimeSpec { 142 fn from(val: RtcTime) -> Self { 143 let instant = Instant::mktime64( 144 val.year_real() as u32, 145 (val.month + 1) as u32, 146 (val.mday) as u32, 147 val.hour as u32, 148 val.minute as u32, 149 val.second as u32, 150 ); 151 152 /* 注意:RTC 仅存储完整的秒数。它是任意的,它存储的是最接近的值还是 153 * 分割秒数截断的值。然而,重要的是我们使用它来存储截断的值。这是因为 154 * 否则在 RTC 同步函数中,需要读取 both xtime.tv_sec 和 xtime.tv_nsec。 155 * 在某些处理器上(例如 ARM),对 >32位的原子读取是不可行的。所以, 156 * 存储最接近的值会减慢同步 API 的速度。因此,这里我们存储截断的值 157 * 并在后面加上 0.5s 的最佳猜测。 158 */ 159 PosixTimeSpec::new(instant.secs(), (NSEC_PER_SEC >> 1).into()) 160 } 161 } 162 163 /// 全局默认rtc的优先级 164 #[allow(dead_code)] 165 #[derive(Debug, Default, PartialEq, PartialOrd, Clone, Copy)] 166 pub enum GeneralRtcPriority { 167 #[default] 168 L0 = 0, 169 L1, 170 } 171