Skip to content

Commit

Permalink
Create clock module (#691)
Browse files Browse the repository at this point in the history
* Move CMOS and RTC to clk module

* Add timer to clk module

* Move clocks to clk module

* Rename uptime and realtime to boot and epoch time

* Refactor module

* Refactor sync functions

* Return error instead of invoking the unimplemented macro in device files
  • Loading branch information
vinc authored Oct 21, 2024
1 parent 92acc3e commit 4d7e2b0
Show file tree
Hide file tree
Showing 45 changed files with 472 additions and 414 deletions.
3 changes: 2 additions & 1 deletion doc/lisp.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ MOROS Lisp is a Lisp-1 dialect inspired by Scheme, Clojure, and Ruby!
- `read`, `write`, `append`
- `read-binary`, `write-binary`, `append-binary`
- `read-line`, `read-char`
- `uptime`, `realtime`
- `clock/boot`, `clock/epoch`
- `p`, `print`, `eprint`, `error`

### Math Library
Expand Down Expand Up @@ -176,6 +176,7 @@ Would produce the following output:

### Unreleased
- Add `dirname`, `filename`, `eprint`, and `error` functions
- Rename `uptime` to `clk/boot` and `realtime` to `clk/epoch`

### 0.7.1 (2024-06-20)
- Add `floor`, `ceil`, and `round` functions
Expand Down
16 changes: 8 additions & 8 deletions doc/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ commands to test the system or `install` to setup the
Created '/dev/ata/1/0'
Created '/dev/ata/1/1'
Created '/dev/clk'
Created '/dev/clk/uptime'
Created '/dev/clk/realtime'
Created '/dev/rtc'
Created '/dev/clk/boot'
Created '/dev/clk/epoch'
Created '/dev/clk/rtc'
Created '/dev/null'
Created '/dev/random'
Created '/dev/console'
Expand Down Expand Up @@ -270,7 +270,7 @@ You can print the date with `date`:
You can update the real time clock by writing the correct time to its device
file:

> print "2023-03-21 10:00:00" => /dev/rtc
> print "2023-03-21 10:00:00" => /dev/clk/rtc

> date
2023-03-21 10:00:00 +0000
Expand All @@ -297,12 +297,12 @@ Add `env TZ 7200` to `/ini/boot.sh` before `shell` to save the timezone:

There's a device file to get the number of seconds elapsed since Unix Epoch:

> read /dev/clk/realtime
> read /dev/clk/epoch
1682105344.624905

And another one since boot:

> read /dev/clk/uptime
> read /dev/clk/boot
1169.384929

## Aliases
Expand All @@ -312,7 +312,7 @@ You can add custom commands to the shell with the `alias` command.
For example you can define an `uptime` command that will read the device file
described above:

> alias uptime "read /dev/clk/uptime"
> alias uptime "read /dev/clk/boot"

> uptime
1406.304852
Expand Down Expand Up @@ -377,5 +377,5 @@ There is also a `ntp` script to synchronize the clock over the network:
> ntp
2023-03-21 10:00:00

> ntp => /dev/rtc
> ntp => /dev/clk/rtc
[12.111156] RTC 2023-03-21 10:00:00 +0000
2 changes: 1 addition & 1 deletion doc/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,5 @@ passed as an argument or defined in `/ini/ntp`:

It can be used to synchronize the real-time clock (RTC):

> ntp => /dev/rtc
> ntp => /dev/clk/rtc
[42.123456] RTC 2023-03-21 10:00:00 +0000
12 changes: 6 additions & 6 deletions dsk/lib/lisp/file.lsp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@

# Clocks

(def (uptime)
"Returns the current value of the uptime clock"
(binary->number (read-binary "/dev/clk/uptime") "float"))
(def (clock/boot)
"Returns the number of seconds since boot"
(binary->number (read-binary "/dev/clk/boot") "float"))

(def (realtime)
"Returns the current value of the realtime clock"
(binary->number (read-binary "/dev/clk/realtime") "float"))
(def (clock/epoch)
"Returns the number of seconds since epoch"
(binary->number (read-binary "/dev/clk/epoch") "float"))

# Path

Expand Down
2 changes: 1 addition & 1 deletion dsk/tmp/lisp/geotime.lsp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

(print
(if (= (len args) 1)
(geotime (str->num (first args)) (realtime))
(geotime (str->num (first args)) (clk/epoch))
(if (= (len args) 2)
(geotime (str->num (first args)) (str->num (second args)))
"Usage: geotime <longitude> [<timestamp>]")))
8 changes: 4 additions & 4 deletions src/api/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ fn read_float(path: &str) -> f64 {
0.0
}

pub fn uptime() -> f64 {
read_float("/dev/clk/uptime")
pub fn boot_time() -> f64 {
read_float("/dev/clk/boot")
}

pub fn realtime() -> f64 {
read_float("/dev/clk/realtime")
pub fn epoch_time() -> f64 {
read_float("/dev/clk/epoch")
}
6 changes: 3 additions & 3 deletions src/api/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ fn device_type(name: &str) -> Result<DeviceType, ()> {
"file" => Ok(DeviceType::File),
"console" => Ok(DeviceType::Console),
"random" => Ok(DeviceType::Random),
"uptime" => Ok(DeviceType::Uptime),
"realtime" => Ok(DeviceType::Realtime),
"rtc" => Ok(DeviceType::RTC),
"clk-boot" => Ok(DeviceType::BootTime),
"clk-epoch" => Ok(DeviceType::EpochTime),
"clk-rtc" => Ok(DeviceType::RTC),
"tcp" => Ok(DeviceType::TcpSocket),
"udp" => Ok(DeviceType::UdpSocket),
"vga-buffer" => Ok(DeviceType::VgaBuffer),
Expand Down
2 changes: 1 addition & 1 deletion src/api/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn now() -> OffsetDateTime {
}

pub fn now_utc() -> OffsetDateTime {
let s = clock::realtime(); // Since Unix Epoch
let s = clock::epoch_time(); // Since Unix Epoch
let ns = Duration::nanoseconds(
libm::floor(1e9 * (s - libm::floor(s))) as i64
);
Expand Down
2 changes: 1 addition & 1 deletion src/bin/geocal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn main(args: &[&str]) {
let timestamp = if args.len() == 4 {
args[3].parse().unwrap()
} else {
clock::realtime() as i64
clock::epoch_time() as i64
};

let week;
Expand Down
2 changes: 1 addition & 1 deletion src/bin/geodate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn main(args: &[&str]) {
let timestamp = if args.len() == 3 {
args[2].parse().expect("Could not parse timestamp")
} else {
clock::realtime()
clock::epoch_time()
};

let t = geodate::get_formatted_date(format, timestamp as i64, longitude);
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn init(boot_info: &'static BootInfo) {
sys::pic::init(); // Enable interrupts
sys::serial::init();
sys::keyboard::init();
sys::time::init();
sys::clk::init();

let v = option_env!("MOROS_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"));
log!("SYS MOROS v{}", v);
Expand All @@ -42,7 +42,8 @@ pub fn init(boot_info: &'static BootInfo) {
sys::net::init(); // Require PCI
sys::ata::init();
sys::fs::init(); // Require ATA
sys::clock::init(); // Require MEM

log!("RTC {}", sys::clk::date());
}

#[allow(dead_code)]
Expand Down
10 changes: 5 additions & 5 deletions src/sys/ata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl Bus {
}

fn wait(&mut self, ns: u64) {
sys::time::nanowait(ns);
sys::clk::wait(ns);
}

fn clear_interrupt(&mut self) -> u8 {
Expand Down Expand Up @@ -132,9 +132,9 @@ impl Bus {
}

fn poll(&mut self, bit: Status, val: bool) -> Result<(), ()> {
let start = sys::clock::uptime();
let start = sys::clk::boot_time();
while self.status().get_bit(bit as usize) != val {
if sys::clock::uptime() - start > 1.0 {
if sys::clk::boot_time() - start > 1.0 {
debug!(
"ATA hanged while polling {:?} bit in status register",
bit
Expand Down Expand Up @@ -164,7 +164,7 @@ impl Bus {
// Bit 7 => 1
self.drive_register.write(0xA0 | (drive << 4))
}
sys::time::nanowait(400); // Wait at least 400 ns
sys::clk::wait(400); // Wait at least 400 ns
self.poll(Status::BSY, false)?;
self.poll(Status::DRQ, false)?;
Ok(())
Expand Down Expand Up @@ -392,7 +392,7 @@ impl FileIO for Drive {
}

fn write(&mut self, _buf: &[u8]) -> Result<usize, ()> {
unimplemented!();
Err(())
}

fn close(&mut self) {
Expand Down
54 changes: 54 additions & 0 deletions src/sys/clk/boot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use super::timer;

use crate::api::fs::{FileIO, IO};

#[derive(Debug, Clone)]
pub struct BootTime;

impl BootTime {
pub fn new() -> Self {
Self {}
}

pub fn size() -> usize {
core::mem::size_of::<f64>()
}
}

impl FileIO for BootTime {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, ()> {
let time = boot_time().to_be_bytes();
let n = time.len();
if buf.len() >= n {
buf[0..n].clone_from_slice(&time);
Ok(n)
} else {
Err(())
}
}

fn write(&mut self, _buf: &[u8]) -> Result<usize, ()> {
Err(())
}

fn close(&mut self) {}

fn poll(&mut self, event: IO) -> bool {
match event {
IO::Read => true,
IO::Write => false,
}
}
}

/// Returns the number of seconds since boot.
///
/// This clock is monotonic.
pub fn boot_time() -> f64 {
timer::time_between_ticks() * timer::ticks() as f64
}

#[test_case]
fn test_boot_time() {
assert!(boot_time() > 0.0);
}
Loading

0 comments on commit 4d7e2b0

Please sign in to comment.