1 use core::{ 2 fmt, 3 ops::{self, Sub}, 4 }; 5 6 use self::timekeep::ktime_get_real_ns; 7 8 pub mod clocksource; 9 pub mod jiffies; 10 pub mod sleep; 11 pub mod syscall; 12 pub mod timeconv; 13 pub mod timekeep; 14 pub mod timekeeping; 15 pub mod timer; 16 /* Time structures. (Partitially taken from smoltcp) 17 18 The `time` module contains structures used to represent both 19 absolute and relative time. 20 21 - [Instant] is used to represent absolute time. 22 - [Duration] is used to represent relative time. 23 24 [Instant]: struct.Instant.html 25 [Duration]: struct.Duration.html 26 */ 27 #[allow(dead_code)] 28 pub const MSEC_PER_SEC: u32 = 1000; 29 #[allow(dead_code)] 30 pub const USEC_PER_MSEC: u32 = 1000; 31 #[allow(dead_code)] 32 pub const NSEC_PER_USEC: u32 = 1000; 33 #[allow(dead_code)] 34 pub const NSEC_PER_MSEC: u32 = 1000000; 35 #[allow(dead_code)] 36 pub const USEC_PER_SEC: u32 = 1000000; 37 #[allow(dead_code)] 38 pub const NSEC_PER_SEC: u32 = 1000000000; 39 #[allow(dead_code)] 40 pub const FSEC_PER_SEC: u64 = 1000000000000000; 41 42 /// 表示时间的结构体,符合POSIX标准。 43 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 44 #[repr(C)] 45 pub struct TimeSpec { 46 pub tv_sec: i64, 47 pub tv_nsec: i64, 48 } 49 50 impl TimeSpec { 51 #[allow(dead_code)] 52 pub fn new(sec: i64, nsec: i64) -> TimeSpec { 53 return TimeSpec { 54 tv_sec: sec, 55 tv_nsec: nsec, 56 }; 57 } 58 } 59 60 impl Sub for TimeSpec { 61 type Output = Duration; 62 fn sub(self, rhs: Self) -> Self::Output { 63 let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0); 64 let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0); 65 Duration::from_micros((sec * 1000000 + nsec / 1000) as u64) 66 } 67 } 68 69 impl From<Duration> for TimeSpec { 70 fn from(dur: Duration) -> Self { 71 TimeSpec { 72 tv_sec: dur.total_micros() as i64 / 1000000, 73 tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000, 74 } 75 } 76 } 77 78 impl Into<Duration> for TimeSpec { 79 fn into(self) -> Duration { 80 Duration::from_micros(self.tv_sec as u64 * 1000000 + self.tv_nsec as u64 / 1000) 81 } 82 } 83 84 /// A representation of an absolute time value. 85 /// 86 /// The `Instant` type is a wrapper around a `i64` value that 87 /// represents a number of microseconds, monotonically increasing 88 /// since an arbitrary moment in time, such as system startup. 89 /// 90 /// * A value of `0` is inherently arbitrary. 91 /// * A value less than `0` indicates a time before the starting 92 /// point. 93 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 94 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 95 pub struct Instant { 96 micros: i64, 97 } 98 99 #[allow(dead_code)] 100 impl Instant { 101 pub const ZERO: Instant = Instant::from_micros_const(0); 102 103 /// Create a new `Instant` from a number of microseconds. 104 pub fn from_micros<T: Into<i64>>(micros: T) -> Instant { 105 Instant { 106 micros: micros.into(), 107 } 108 } 109 110 pub const fn from_micros_const(micros: i64) -> Instant { 111 Instant { micros } 112 } 113 114 /// Create a new `Instant` from a number of milliseconds. 115 pub fn from_millis<T: Into<i64>>(millis: T) -> Instant { 116 Instant { 117 micros: millis.into() * 1000, 118 } 119 } 120 121 /// Create a new `Instant` from a number of milliseconds. 122 pub const fn from_millis_const(millis: i64) -> Instant { 123 Instant { 124 micros: millis * 1000, 125 } 126 } 127 128 /// Create a new `Instant` from a number of seconds. 129 pub fn from_secs<T: Into<i64>>(secs: T) -> Instant { 130 Instant { 131 micros: secs.into() * 1000000, 132 } 133 } 134 135 /// Create a new `Instant` from the current time 136 pub fn now() -> Instant { 137 Self::from_micros(ktime_get_real_ns() / 1000) 138 } 139 140 /// The fractional number of milliseconds that have passed 141 /// since the beginning of time. 142 pub const fn millis(&self) -> i64 { 143 self.micros % 1000000 / 1000 144 } 145 146 /// The fractional number of microseconds that have passed 147 /// since the beginning of time. 148 pub const fn micros(&self) -> i64 { 149 self.micros % 1000000 150 } 151 152 /// The number of whole seconds that have passed since the 153 /// beginning of time. 154 pub const fn secs(&self) -> i64 { 155 self.micros / 1000000 156 } 157 158 /// The total number of milliseconds that have passed since 159 /// the beginning of time. 160 pub const fn total_millis(&self) -> i64 { 161 self.micros / 1000 162 } 163 /// The total number of milliseconds that have passed since 164 /// the beginning of time. 165 pub const fn total_micros(&self) -> i64 { 166 self.micros 167 } 168 } 169 170 impl fmt::Display for Instant { 171 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 172 write!(f, "{}.{:0>3}s", self.secs(), self.millis()) 173 } 174 } 175 176 impl ops::Add<Duration> for Instant { 177 type Output = Instant; 178 179 fn add(self, rhs: Duration) -> Instant { 180 Instant::from_micros(self.micros + rhs.total_micros() as i64) 181 } 182 } 183 184 impl ops::AddAssign<Duration> for Instant { 185 fn add_assign(&mut self, rhs: Duration) { 186 self.micros += rhs.total_micros() as i64; 187 } 188 } 189 190 impl ops::Sub<Duration> for Instant { 191 type Output = Instant; 192 193 fn sub(self, rhs: Duration) -> Instant { 194 Instant::from_micros(self.micros - rhs.total_micros() as i64) 195 } 196 } 197 198 impl ops::SubAssign<Duration> for Instant { 199 fn sub_assign(&mut self, rhs: Duration) { 200 self.micros -= rhs.total_micros() as i64; 201 } 202 } 203 204 impl ops::Sub<Instant> for Instant { 205 type Output = Duration; 206 207 fn sub(self, rhs: Instant) -> Duration { 208 Duration::from_micros((self.micros - rhs.micros).unsigned_abs()) 209 } 210 } 211 212 /// A relative amount of time. 213 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 214 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 215 pub struct Duration { 216 micros: u64, 217 } 218 219 impl Duration { 220 pub const ZERO: Duration = Duration::from_micros(0); 221 /// Create a new `Duration` from a number of microseconds. 222 pub const fn from_micros(micros: u64) -> Duration { 223 Duration { micros } 224 } 225 226 /// Create a new `Duration` from a number of milliseconds. 227 pub const fn from_millis(millis: u64) -> Duration { 228 Duration { 229 micros: millis * 1000, 230 } 231 } 232 233 /// Create a new `Instant` from a number of seconds. 234 pub const fn from_secs(secs: u64) -> Duration { 235 Duration { 236 micros: secs * 1000000, 237 } 238 } 239 240 /// The fractional number of milliseconds in this `Duration`. 241 pub const fn millis(&self) -> u64 { 242 self.micros / 1000 % 1000 243 } 244 245 /// The fractional number of milliseconds in this `Duration`. 246 pub const fn micros(&self) -> u64 { 247 self.micros % 1000000 248 } 249 250 /// The number of whole seconds in this `Duration`. 251 pub const fn secs(&self) -> u64 { 252 self.micros / 1000000 253 } 254 255 /// The total number of milliseconds in this `Duration`. 256 pub const fn total_millis(&self) -> u64 { 257 self.micros / 1000 258 } 259 260 /// The total number of microseconds in this `Duration`. 261 pub const fn total_micros(&self) -> u64 { 262 self.micros 263 } 264 } 265 266 impl fmt::Display for Duration { 267 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 268 write!(f, "{}.{:03}s", self.secs(), self.millis()) 269 } 270 } 271 272 impl ops::Add<Duration> for Duration { 273 type Output = Duration; 274 275 fn add(self, rhs: Duration) -> Duration { 276 Duration::from_micros(self.micros + rhs.total_micros()) 277 } 278 } 279 280 impl ops::AddAssign<Duration> for Duration { 281 fn add_assign(&mut self, rhs: Duration) { 282 self.micros += rhs.total_micros(); 283 } 284 } 285 286 impl ops::Sub<Duration> for Duration { 287 type Output = Duration; 288 289 fn sub(self, rhs: Duration) -> Duration { 290 Duration::from_micros( 291 self.micros 292 .checked_sub(rhs.total_micros()) 293 .expect("overflow when subtracting durations"), 294 ) 295 } 296 } 297 298 impl ops::SubAssign<Duration> for Duration { 299 fn sub_assign(&mut self, rhs: Duration) { 300 self.micros = self 301 .micros 302 .checked_sub(rhs.total_micros()) 303 .expect("overflow when subtracting durations"); 304 } 305 } 306 307 impl ops::Mul<u32> for Duration { 308 type Output = Duration; 309 310 fn mul(self, rhs: u32) -> Duration { 311 Duration::from_micros(self.micros * rhs as u64) 312 } 313 } 314 315 impl ops::MulAssign<u32> for Duration { 316 fn mul_assign(&mut self, rhs: u32) { 317 self.micros *= rhs as u64; 318 } 319 } 320 321 impl ops::Div<u32> for Duration { 322 type Output = Duration; 323 324 fn div(self, rhs: u32) -> Duration { 325 Duration::from_micros(self.micros / rhs as u64) 326 } 327 } 328 329 impl ops::DivAssign<u32> for Duration { 330 fn div_assign(&mut self, rhs: u32) { 331 self.micros /= rhs as u64; 332 } 333 } 334 335 impl ops::Shl<u32> for Duration { 336 type Output = Duration; 337 338 fn shl(self, rhs: u32) -> Duration { 339 Duration::from_micros(self.micros << rhs) 340 } 341 } 342 343 impl ops::ShlAssign<u32> for Duration { 344 fn shl_assign(&mut self, rhs: u32) { 345 self.micros <<= rhs; 346 } 347 } 348 349 impl ops::Shr<u32> for Duration { 350 type Output = Duration; 351 352 fn shr(self, rhs: u32) -> Duration { 353 Duration::from_micros(self.micros >> rhs) 354 } 355 } 356 357 impl ops::ShrAssign<u32> for Duration { 358 fn shr_assign(&mut self, rhs: u32) { 359 self.micros >>= rhs; 360 } 361 } 362 363 impl From<::core::time::Duration> for Duration { 364 fn from(other: ::core::time::Duration) -> Duration { 365 Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64) 366 } 367 } 368 369 impl From<Duration> for ::core::time::Duration { 370 fn from(val: Duration) -> Self { 371 ::core::time::Duration::from_micros(val.total_micros()) 372 } 373 } 374 375 /// 支持与smoltcp的时间转换 376 impl From<smoltcp::time::Instant> for Instant { 377 fn from(val: smoltcp::time::Instant) -> Self { 378 Instant::from_micros(val.micros()) 379 } 380 } 381 382 impl Into<smoltcp::time::Instant> for Instant { 383 fn into(self) -> smoltcp::time::Instant { 384 smoltcp::time::Instant::from_millis(self.millis()) 385 } 386 } 387 388 /// 支持与smoltcp的时间转换 389 impl From<smoltcp::time::Duration> for Duration { 390 fn from(val: smoltcp::time::Duration) -> Self { 391 Duration::from_micros(val.micros()) 392 } 393 } 394 395 impl Into<smoltcp::time::Duration> for Duration { 396 fn into(self) -> smoltcp::time::Duration { 397 smoltcp::time::Duration::from_millis(self.millis()) 398 } 399 } 400 401 pub trait TimeArch { 402 /// Get CPU cycles (Read from register) 403 fn get_cycles() -> usize; 404 } 405