aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--heterogeneous/src/lib.rs9
-rw-r--r--homogeneous/src/lib.rs9
-rw-r--r--src/cyccnt.rs16
-rw-r--r--src/lib.rs14
-rw-r--r--src/tq.rs10
5 files changed, 41 insertions, 17 deletions
diff --git a/heterogeneous/src/lib.rs b/heterogeneous/src/lib.rs
index 3288bfe0..95ff184d 100644
--- a/heterogeneous/src/lib.rs
+++ b/heterogeneous/src/lib.rs
@@ -8,7 +8,7 @@ use core::{
};
use bare_metal::Nr;
-use rtfm::{Monotonic, MultiCore};
+use rtfm::{Fraction, Monotonic, MultiCore};
// both cores have the exact same interrupts
pub use Interrupt_0 as Interrupt_1;
@@ -24,8 +24,11 @@ pub struct MT;
impl Monotonic for MT {
type Instant = Instant;
- fn ratio() -> u32 {
- 1
+ fn ratio() -> Fraction {
+ Fraction {
+ numerator: 1,
+ denominator: 1,
+ }
}
unsafe fn reset() {
diff --git a/homogeneous/src/lib.rs b/homogeneous/src/lib.rs
index 3288bfe0..95ff184d 100644
--- a/homogeneous/src/lib.rs
+++ b/homogeneous/src/lib.rs
@@ -8,7 +8,7 @@ use core::{
};
use bare_metal::Nr;
-use rtfm::{Monotonic, MultiCore};
+use rtfm::{Fraction, Monotonic, MultiCore};
// both cores have the exact same interrupts
pub use Interrupt_0 as Interrupt_1;
@@ -24,8 +24,11 @@ pub struct MT;
impl Monotonic for MT {
type Instant = Instant;
- fn ratio() -> u32 {
- 1
+ fn ratio() -> Fraction {
+ Fraction {
+ numerator: 1,
+ denominator: 1,
+ }
}
unsafe fn reset() {
diff --git a/src/cyccnt.rs b/src/cyccnt.rs
index 468aa712..c8a1b7ee 100644
--- a/src/cyccnt.rs
+++ b/src/cyccnt.rs
@@ -10,9 +10,15 @@ use core::{
use cortex_m::peripheral::DWT;
+use crate::Fraction;
+
/// A measurement of the CYCCNT. Opaque and useful only with `Duration`
///
/// This data type is only available on ARMv7-M
+///
+/// Note that this value is tied to the CYCCNT of one core and that sending it a different core
+/// makes it lose its meaning -- each Cortex-M core has its own CYCCNT counter and these are usually
+/// unsynchronized and they may even be running at different frequencies.
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Instant {
inner: i32,
@@ -21,7 +27,6 @@ pub struct Instant {
unsafe impl Sync for Instant {}
-#[cfg(not(feature = "heterogeneous"))]
unsafe impl Send for Instant {}
impl Instant {
@@ -182,15 +187,16 @@ impl U32Ext for u32 {
}
/// Implementation of the `Monotonic` trait based on CYCle CouNTer
-#[cfg(not(feature = "heterogeneous"))]
pub struct CYCCNT;
-#[cfg(not(feature = "heterogeneous"))]
impl crate::Monotonic for CYCCNT {
type Instant = Instant;
- fn ratio() -> u32 {
- 1
+ fn ratio() -> Fraction {
+ Fraction {
+ numerator: 1,
+ denominator: 1,
+ }
}
unsafe fn reset() {
diff --git a/src/lib.rs b/src/lib.rs
index decd2da1..22eff5ac 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -116,13 +116,25 @@ impl From<cortex_m::Peripherals> for Peripherals {
}
}
+/// A fraction
+pub struct Fraction {
+ /// The numerator
+ pub numerator: u32,
+
+ /// The denominator
+ pub denominator: u32,
+}
+
/// A monotonic clock / counter
pub trait Monotonic {
/// A measurement of this clock
type Instant: Copy + Ord + Sub;
/// The ratio between the SysTick (system timer) frequency and this clock frequency
- fn ratio() -> u32;
+ ///
+ /// The ratio must be expressed in *reduced* `Fraction` form to prevent overflows. That is
+ /// `2 / 3` instead of `4 / 6`
+ fn ratio() -> Fraction;
/// Returns the current time
fn now() -> Self::Instant;
diff --git a/src/tq.rs b/src/tq.rs
index 4f9b6e7e..4edb40a7 100644
--- a/src/tq.rs
+++ b/src/tq.rs
@@ -62,11 +62,11 @@ where
// set a new timeout
const MAX: u32 = 0x00ffffff;
- let dur = match (instant - now)
- .try_into()
- .ok()
- .and_then(|x| x.checked_mul(M::ratio()))
- {
+ let ratio = M::ratio();
+ let dur = match (instant - now).try_into().ok().and_then(|x| {
+ x.checked_mul(ratio.numerator)
+ .map(|x| x / ratio.denominator)
+ }) {
None => MAX,
Some(x) => cmp::min(MAX, x),
};