1 use core::{ 2 fmt, 3 intrinsics::unlikely, 4 ops::{self, Sub}, 5 }; 6 7 use crate::arch::CurrentTimeArch; 8 9 use self::timekeep::ktime_get_real_ns; 10 11 pub mod clocksource; 12 pub mod jiffies; 13 pub mod sleep; 14 pub mod syscall; 15 pub mod timeconv; 16 pub mod timekeep; 17 pub mod timekeeping; 18 pub mod timer; 19 20 /* Time structures. (Partitially taken from smoltcp) 21 22 The `time` module contains structures used to represent both 23 absolute and relative time. 24 25 - [Instant] is used to represent absolute time. 26 - [Duration] is used to represent relative time. 27 28 [Instant]: struct.Instant.html 29 [Duration]: struct.Duration.html 30 */ 31 #[allow(dead_code)] 32 pub const MSEC_PER_SEC: u32 = 1000; 33 #[allow(dead_code)] 34 pub const USEC_PER_MSEC: u32 = 1000; 35 #[allow(dead_code)] 36 pub const NSEC_PER_USEC: u32 = 1000; 37 #[allow(dead_code)] 38 pub const NSEC_PER_MSEC: u32 = 1000000; 39 #[allow(dead_code)] 40 pub const USEC_PER_SEC: u32 = 1000000; 41 #[allow(dead_code)] 42 pub const NSEC_PER_SEC: u32 = 1000000000; 43 #[allow(dead_code)] 44 pub const FSEC_PER_SEC: u64 = 1000000000000000; 45 46 /// 表示时间的结构体,符合POSIX标准。 47 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 48 #[repr(C)] 49 pub struct TimeSpec { 50 pub tv_sec: i64, 51 pub tv_nsec: i64, 52 } 53 54 impl TimeSpec { 55 #[allow(dead_code)] 56 pub fn new(sec: i64, nsec: i64) -> TimeSpec { 57 return TimeSpec { 58 tv_sec: sec, 59 tv_nsec: nsec, 60 }; 61 } 62 63 /// 获取当前时间 64 pub fn now() -> Self { 65 #[cfg(target_arch = "x86_64")] 66 { 67 use crate::arch::driver::tsc::TSCManager; 68 let khz = TSCManager::cpu_khz(); 69 if unlikely(khz == 0) { 70 return TimeSpec::default(); 71 } else { 72 return Self::from(Duration::from_millis( 73 CurrentTimeArch::get_cycles() as u64 / khz, 74 )); 75 } 76 } 77 78 #[cfg(target_arch = "riscv64")] 79 { 80 return TimeSpec::new(0, 0); 81 } 82 } 83 } 84 85 impl Sub for TimeSpec { 86 type Output = Duration; 87 fn sub(self, rhs: Self) -> Self::Output { 88 let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0); 89 let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0); 90 Duration::from_micros((sec * 1000000 + nsec / 1000) as u64) 91 } 92 } 93 94 impl From<Duration> for TimeSpec { 95 fn from(dur: Duration) -> Self { 96 TimeSpec { 97 tv_sec: dur.total_micros() as i64 / 1000000, 98 tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000, 99 } 100 } 101 } 102 103 impl From<TimeSpec> for Duration { 104 fn from(val: TimeSpec) -> Self { 105 Duration::from_micros(val.tv_sec as u64 * 1000000 + val.tv_nsec as u64 / 1000) 106 } 107 } 108 109 /// A representation of an absolute time value. 110 /// 111 /// The `Instant` type is a wrapper around a `i64` value that 112 /// represents a number of microseconds, monotonically increasing 113 /// since an arbitrary moment in time, such as system startup. 114 /// 115 /// * A value of `0` is inherently arbitrary. 116 /// * A value less than `0` indicates a time before the starting 117 /// point. 118 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 119 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 120 pub struct Instant { 121 micros: i64, 122 } 123 124 #[allow(dead_code)] 125 impl Instant { 126 pub const ZERO: Instant = Instant::from_micros_const(0); 127 128 /// mktime64 - 将日期转换为秒。 129 /// 130 /// ## 参数 131 /// 132 /// - year0: 要转换的年份 133 /// - mon0: 要转换的月份 134 /// - day: 要转换的天 135 /// - hour: 要转换的小时 136 /// - min: 要转换的分钟 137 /// - sec: 要转换的秒 138 /// 139 /// 将公历日期转换为1970-01-01 00:00:00以来的秒数。 140 /// 假设输入为正常的日期格式,即1980-12-31 23:59:59 => 年份=1980, 月=12, 日=31, 时=23, 分=59, 秒=59。 141 /// 142 /// [For the Julian calendar(俄罗斯在1917年之前使用,英国及其殖民地在大西洋1752年之前使用, 143 /// 其他地方在1582年之前使用,某些社区仍然在使用)省略-year/100+year/400项, 144 /// 并在结果上加10。] 145 /// 146 /// 这个算法最初由高斯(我认为是)发表。 147 /// 148 /// 要表示闰秒,可以通过将sec设为60(在ISO 8601允许)来调用此函数。 149 /// 闰秒与随后的秒一样处理,因为它们在UNIX时间中不存在。 150 /// 151 /// 支持将午夜作为当日末尾的24:00:00编码 - 即明天的午夜(在ISO 8601允许)。 152 /// 153 /// ## 返回 154 /// 155 /// 返回:给定输入日期自1970-01-01 00:00:00以来的秒数 156 pub fn mktime64(year0: u32, mon0: u32, day: u32, hour: u32, min: u32, sec: u32) -> Self { 157 let mut mon: i64 = mon0.into(); 158 let mut year: u64 = year0.into(); 159 let day: u64 = day.into(); 160 let hour: u64 = hour.into(); 161 let min: u64 = min.into(); 162 let sec: u64 = sec.into(); 163 164 mon -= 2; 165 /* 1..12 -> 11,12,1..10 */ 166 if mon <= 0 { 167 /* Puts Feb last since it has leap day */ 168 mon += 12; 169 year -= 1; 170 } 171 let mon = mon as u64; 172 173 let secs = ((((year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + year * 365 174 - 719499) 175 * 24 + hour) /* now have hours - midnight tomorrow handled here */ 176 * 60 + min)/* now have minutes */ 177 * 60 178 + sec; /* finally seconds */ 179 180 Self::from_secs(secs as i64) 181 } 182 183 /// Create a new `Instant` from a number of microseconds. 184 pub fn from_micros<T: Into<i64>>(micros: T) -> Instant { 185 Instant { 186 micros: micros.into(), 187 } 188 } 189 190 pub const fn from_micros_const(micros: i64) -> Instant { 191 Instant { micros } 192 } 193 194 /// Create a new `Instant` from a number of milliseconds. 195 pub fn from_millis<T: Into<i64>>(millis: T) -> Instant { 196 Instant { 197 micros: millis.into() * 1000, 198 } 199 } 200 201 /// Create a new `Instant` from a number of milliseconds. 202 pub const fn from_millis_const(millis: i64) -> Instant { 203 Instant { 204 micros: millis * 1000, 205 } 206 } 207 208 /// Create a new `Instant` from a number of seconds. 209 pub fn from_secs<T: Into<i64>>(secs: T) -> Instant { 210 Instant { 211 micros: secs.into() * 1000000, 212 } 213 } 214 215 /// Create a new `Instant` from the current time 216 pub fn now() -> Instant { 217 Self::from_micros(ktime_get_real_ns() / 1000) 218 } 219 220 /// The fractional number of milliseconds that have passed 221 /// since the beginning of time. 222 pub const fn millis(&self) -> i64 { 223 self.micros % 1000000 / 1000 224 } 225 226 /// The fractional number of microseconds that have passed 227 /// since the beginning of time. 228 pub const fn micros(&self) -> i64 { 229 self.micros % 1000000 230 } 231 232 /// The number of whole seconds that have passed since the 233 /// beginning of time. 234 pub const fn secs(&self) -> i64 { 235 self.micros / 1000000 236 } 237 238 /// The total number of milliseconds that have passed since 239 /// the beginning of time. 240 pub const fn total_millis(&self) -> i64 { 241 self.micros / 1000 242 } 243 /// The total number of milliseconds that have passed since 244 /// the beginning of time. 245 pub const fn total_micros(&self) -> i64 { 246 self.micros 247 } 248 } 249 250 impl fmt::Display for Instant { 251 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 252 write!(f, "{}.{:0>3}s", self.secs(), self.millis()) 253 } 254 } 255 256 impl ops::Add<Duration> for Instant { 257 type Output = Instant; 258 259 fn add(self, rhs: Duration) -> Instant { 260 Instant::from_micros(self.micros + rhs.total_micros() as i64) 261 } 262 } 263 264 impl ops::AddAssign<Duration> for Instant { 265 fn add_assign(&mut self, rhs: Duration) { 266 self.micros += rhs.total_micros() as i64; 267 } 268 } 269 270 impl ops::Sub<Duration> for Instant { 271 type Output = Instant; 272 273 fn sub(self, rhs: Duration) -> Instant { 274 Instant::from_micros(self.micros - rhs.total_micros() as i64) 275 } 276 } 277 278 impl ops::SubAssign<Duration> for Instant { 279 fn sub_assign(&mut self, rhs: Duration) { 280 self.micros -= rhs.total_micros() as i64; 281 } 282 } 283 284 impl ops::Sub<Instant> for Instant { 285 type Output = Duration; 286 287 fn sub(self, rhs: Instant) -> Duration { 288 Duration::from_micros((self.micros - rhs.micros).unsigned_abs()) 289 } 290 } 291 292 /// A relative amount of time. 293 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 294 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 295 pub struct Duration { 296 micros: u64, 297 } 298 299 impl Duration { 300 pub const ZERO: Duration = Duration::from_micros(0); 301 /// Create a new `Duration` from a number of microseconds. 302 pub const fn from_micros(micros: u64) -> Duration { 303 Duration { micros } 304 } 305 306 /// Create a new `Duration` from a number of milliseconds. 307 pub const fn from_millis(millis: u64) -> Duration { 308 Duration { 309 micros: millis * 1000, 310 } 311 } 312 313 /// Create a new `Instant` from a number of seconds. 314 pub const fn from_secs(secs: u64) -> Duration { 315 Duration { 316 micros: secs * 1000000, 317 } 318 } 319 320 /// The fractional number of milliseconds in this `Duration`. 321 pub const fn millis(&self) -> u64 { 322 self.micros / 1000 % 1000 323 } 324 325 /// The fractional number of milliseconds in this `Duration`. 326 pub const fn micros(&self) -> u64 { 327 self.micros % 1000000 328 } 329 330 /// The number of whole seconds in this `Duration`. 331 pub const fn secs(&self) -> u64 { 332 self.micros / 1000000 333 } 334 335 /// The total number of milliseconds in this `Duration`. 336 pub const fn total_millis(&self) -> u64 { 337 self.micros / 1000 338 } 339 340 /// The total number of microseconds in this `Duration`. 341 pub const fn total_micros(&self) -> u64 { 342 self.micros 343 } 344 } 345 346 impl fmt::Display for Duration { 347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 348 write!(f, "{}.{:03}s", self.secs(), self.millis()) 349 } 350 } 351 352 impl ops::Add<Duration> for Duration { 353 type Output = Duration; 354 355 fn add(self, rhs: Duration) -> Duration { 356 Duration::from_micros(self.micros + rhs.total_micros()) 357 } 358 } 359 360 impl ops::AddAssign<Duration> for Duration { 361 fn add_assign(&mut self, rhs: Duration) { 362 self.micros += rhs.total_micros(); 363 } 364 } 365 366 impl ops::Sub<Duration> for Duration { 367 type Output = Duration; 368 369 fn sub(self, rhs: Duration) -> Duration { 370 Duration::from_micros( 371 self.micros 372 .checked_sub(rhs.total_micros()) 373 .expect("overflow when subtracting durations"), 374 ) 375 } 376 } 377 378 impl ops::SubAssign<Duration> for Duration { 379 fn sub_assign(&mut self, rhs: Duration) { 380 self.micros = self 381 .micros 382 .checked_sub(rhs.total_micros()) 383 .expect("overflow when subtracting durations"); 384 } 385 } 386 387 impl ops::Mul<u32> for Duration { 388 type Output = Duration; 389 390 fn mul(self, rhs: u32) -> Duration { 391 Duration::from_micros(self.micros * rhs as u64) 392 } 393 } 394 395 impl ops::MulAssign<u32> for Duration { 396 fn mul_assign(&mut self, rhs: u32) { 397 self.micros *= rhs as u64; 398 } 399 } 400 401 impl ops::Div<u32> for Duration { 402 type Output = Duration; 403 404 fn div(self, rhs: u32) -> Duration { 405 Duration::from_micros(self.micros / rhs as u64) 406 } 407 } 408 409 impl ops::DivAssign<u32> for Duration { 410 fn div_assign(&mut self, rhs: u32) { 411 self.micros /= rhs as u64; 412 } 413 } 414 415 impl ops::Shl<u32> for Duration { 416 type Output = Duration; 417 418 fn shl(self, rhs: u32) -> Duration { 419 Duration::from_micros(self.micros << rhs) 420 } 421 } 422 423 impl ops::ShlAssign<u32> for Duration { 424 fn shl_assign(&mut self, rhs: u32) { 425 self.micros <<= rhs; 426 } 427 } 428 429 impl ops::Shr<u32> for Duration { 430 type Output = Duration; 431 432 fn shr(self, rhs: u32) -> Duration { 433 Duration::from_micros(self.micros >> rhs) 434 } 435 } 436 437 impl ops::ShrAssign<u32> for Duration { 438 fn shr_assign(&mut self, rhs: u32) { 439 self.micros >>= rhs; 440 } 441 } 442 443 impl From<::core::time::Duration> for Duration { 444 fn from(other: ::core::time::Duration) -> Duration { 445 Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64) 446 } 447 } 448 449 impl From<Duration> for ::core::time::Duration { 450 fn from(val: Duration) -> Self { 451 ::core::time::Duration::from_micros(val.total_micros()) 452 } 453 } 454 455 /// 支持与smoltcp的时间转换 456 impl From<smoltcp::time::Instant> for Instant { 457 fn from(val: smoltcp::time::Instant) -> Self { 458 Instant::from_micros(val.micros()) 459 } 460 } 461 462 impl From<Instant> for smoltcp::time::Instant { 463 fn from(val: Instant) -> Self { 464 smoltcp::time::Instant::from_millis(val.millis()) 465 } 466 } 467 468 /// 支持与smoltcp的时间转换 469 impl From<smoltcp::time::Duration> for Duration { 470 fn from(val: smoltcp::time::Duration) -> Self { 471 Duration::from_micros(val.micros()) 472 } 473 } 474 475 impl From<Duration> for smoltcp::time::Duration { 476 fn from(val: Duration) -> Self { 477 smoltcp::time::Duration::from_millis(val.millis()) 478 } 479 } 480 481 pub trait TimeArch { 482 /// Get CPU cycles (Read from register) 483 fn get_cycles() -> usize; 484 485 /// Calculate expire cycles 486 /// 487 /// # Arguments 488 /// 489 /// - `ns` - The time to expire in nanoseconds 490 /// 491 /// # Returns 492 /// 493 /// The expire cycles 494 fn cal_expire_cycles(ns: usize) -> usize; 495 496 /// 将CPU的时钟周期数转换为纳秒 497 fn cycles2ns(cycles: usize) -> usize; 498 } 499