Merge pull request #89 from gendx/add-rng

Add support for the RNG capsule, and a blink_random example app.
diff --git a/examples/panic.rs b/examples/panic.rs
new file mode 100644
index 0000000..4368415
--- /dev/null
+++ b/examples/panic.rs
@@ -0,0 +1,6 @@
+#![no_std]
+
+fn main() {
+    let _ = libtock::LibTock {};
+    panic!("Bye world!");
+}
diff --git a/src/entry_point.rs b/src/entry_point.rs
index 9942b19..e485bad 100644
--- a/src/entry_point.rs
+++ b/src/entry_point.rs
@@ -339,7 +339,7 @@
     // `sbrk` system call to dynamically request heap memory from the kernel, we
     // need to tell `linked_list_allocator` where the heap starts and ends.
     //
-    // Heap size is set using `elf2tab` with `--heap-size` option, which is
+    // Heap size is set using `elf2tab` with `--app-heap` option, which is
     // currently at 1024. If you change the `elf2tab` heap size, make sure to
     // make the corresponding change here.
     const HEAP_SIZE: usize = 1024;
diff --git a/src/lib.rs b/src/lib.rs
index 800beff..3b24797 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -39,3 +39,7 @@
 #[cfg(any(target_arch = "arm", target_arch = "riscv32"))]
 #[global_allocator]
 static ALLOCATOR: linked_list_allocator::LockedHeap = linked_list_allocator::LockedHeap::empty();
+
+// Dummy structure to force importing the panic_handler and other no_std elements when nothing else
+// is imported.
+pub struct LibTock;
diff --git a/src/timer.rs b/src/timer.rs
index 0a1dbfd..6634282 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -6,6 +6,7 @@
 use crate::syscalls;
 use core::cell::Cell;
 use core::isize;
+use core::ops::{Add, AddAssign, Sub};
 
 const DRIVER_NUMBER: usize = 0x00000;
 
@@ -21,7 +22,7 @@
     pub const SUBSCRIBE_CALLBACK: usize = 0;
 }
 
-pub fn sleep(duration: Duration) {
+pub fn sleep(duration: Duration<isize>) {
     let expired = Cell::new(false);
     let mut with_callback = with_callback(|_, _| expired.set(true));
 
@@ -140,7 +141,7 @@
         }
     }
 
-    pub fn set_alarm(&mut self, duration: Duration) -> TockResult<Alarm, SetAlarmError> {
+    pub fn set_alarm(&mut self, duration: Duration<isize>) -> TockResult<Alarm, SetAlarmError> {
         let now = self.get_current_clock();
         let alarm_instant =
             now.num_ticks() as usize + (duration.ms() as usize * self.clock_frequency.hz()) / 1000;
@@ -187,6 +188,10 @@
             1000 * (self.num_ticks / self.clock_frequency.hz() as isize)
         }
     }
+
+    pub fn ms_f64(&self) -> f64 {
+        1000.0 * (self.num_ticks as f64) / (self.clock_frequency.hz() as f64)
+    }
 }
 
 pub struct Alarm {
@@ -209,17 +214,100 @@
     NoMemoryAvailable,
 }
 
-#[derive(Copy, Clone, Debug)]
-pub struct Duration {
-    ms: isize,
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Duration<T> {
+    ms: T,
 }
 
-impl Duration {
-    pub fn from_ms(ms: isize) -> Duration {
+impl<T> Duration<T> {
+    pub const fn from_ms(ms: T) -> Duration<T> {
         Duration { ms }
     }
+}
 
-    pub fn ms(&self) -> isize {
+impl<T> Duration<T>
+where
+    T: Copy,
+{
+    pub fn ms(&self) -> T {
         self.ms
     }
 }
+
+impl<T> Sub for Duration<T>
+where
+    T: Sub<Output = T>,
+{
+    type Output = Duration<T>;
+
+    fn sub(self, other: Duration<T>) -> Duration<T> {
+        Duration {
+            ms: self.ms - other.ms,
+        }
+    }
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct Timestamp<T> {
+    ms: T,
+}
+
+impl<T> Timestamp<T> {
+    pub const fn from_ms(ms: T) -> Timestamp<T> {
+        Timestamp { ms }
+    }
+}
+
+impl<T> Timestamp<T>
+where
+    T: Copy,
+{
+    pub fn ms(&self) -> T {
+        self.ms
+    }
+}
+
+impl Timestamp<isize> {
+    pub fn from_clock_value(value: ClockValue) -> Timestamp<isize> {
+        Timestamp { ms: value.ms() }
+    }
+}
+
+impl Timestamp<f64> {
+    pub fn from_clock_value(value: ClockValue) -> Timestamp<f64> {
+        Timestamp { ms: value.ms_f64() }
+    }
+}
+
+impl<T> Sub for Timestamp<T>
+where
+    T: Sub<Output = T>,
+{
+    type Output = Duration<T>;
+
+    fn sub(self, other: Timestamp<T>) -> Duration<T> {
+        Duration::from_ms(self.ms - other.ms)
+    }
+}
+
+impl<T> Add<Duration<T>> for Timestamp<T>
+where
+    T: Copy + Add<Output = T>,
+{
+    type Output = Timestamp<T>;
+
+    fn add(self, duration: Duration<T>) -> Timestamp<T> {
+        Timestamp {
+            ms: self.ms + duration.ms(),
+        }
+    }
+}
+
+impl<T> AddAssign<Duration<T>> for Timestamp<T>
+where
+    T: Copy + AddAssign,
+{
+    fn add_assign(&mut self, duration: Duration<T>) {
+        self.ms += duration.ms();
+    }
+}