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