Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create clock module #691

Merged
merged 7 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading