1use std::sync::OnceLock;
2
3use core::time::Duration;
4use file_system::Device;
5
6use crate::{Error, Result};
7
8pub static MANAGER: OnceLock<Manager> = OnceLock::new();
9
10pub fn get_instance() -> &'static Manager {
11 MANAGER.get().expect("Time manager is not initialized")
12}
13
14pub fn initialize(driver: Device) -> Result<&'static Manager> {
15 MANAGER.get_or_init(|| Manager::new(driver).expect("Failed to initialize time manager"));
16
17 Ok(get_instance())
18}
19
20pub struct Manager {
21 device: Device,
22 start_time: Duration,
23}
24
25impl Manager {
26 pub fn new(device: Device) -> Result<Self> {
27 let start_time = Self::get_current_time_from_device(&device)?;
28
29 Ok(Self { device, start_time })
30 }
31
32 pub fn get_current_time_since_startup(&self) -> Result<Duration> {
33 let current_time = self.get_current_time()?;
34
35 Ok(current_time.abs_diff(self.start_time))
36 }
37
38 pub fn get_current_time(&self) -> Result<Duration> {
39 Self::get_current_time_from_device(&self.device)
40 }
41
42 fn get_current_time_from_device(device: &Device) -> Result<Duration> {
43 let mut current_time = Duration::default();
44
45 let current_time_raw = unsafe {
46 core::slice::from_raw_parts_mut(
47 &mut current_time as *mut Duration as *mut u8,
48 core::mem::size_of::<Duration>(),
49 )
50 };
51
52 device.read(current_time_raw).map_err(Error::DeviceError)?;
53
54 Ok(current_time)
55 }
56}