All Projects → FluenTech → embedded-time

FluenTech / embedded-time

Licence: Apache-2.0, MIT licenses found Licenses found Apache-2.0 LICENSE-Apache MIT LICENSE-MIT
Time(ing) library (Instant/Duration/Clock/Timer/Period/Frequency) for bare-metal embedded systems

Programming Languages

rust
11053 projects
powershell
5483 projects

Projects that are alternatives of or similar to embedded-time

Ms
Tiny millisecond conversion utility
Stars: ✭ 3,762 (+5125%)
Mutual labels:  conversion, milliseconds
xiaoai-patch
Patching for XiaoAi Speakers, add custom binaries and open source software. Tested on LX06, LX01, LX05, L09A
Stars: ✭ 58 (-19.44%)
Mutual labels:  hardware
roffit
converts nroff man pages to HTML
Stars: ✭ 84 (+16.67%)
Mutual labels:  conversion
Big Honking Button
A simple Eurorack sampler and performance module in a silly package.
Stars: ✭ 45 (-37.5%)
Mutual labels:  hardware
human-computer
A computer that uses nothing but human resources
Stars: ✭ 16 (-77.78%)
Mutual labels:  hardware
pink-0
Ableton Link to clock/reset signals converter
Stars: ✭ 87 (+20.83%)
Mutual labels:  hardware
espism
A low cost ISM radio to wifi gateway
Stars: ✭ 38 (-47.22%)
Mutual labels:  hardware
tapasco
The Task Parallel System Composer (TaPaSCo)
Stars: ✭ 66 (-8.33%)
Mutual labels:  hardware
kerntroller
No description or website provided.
Stars: ✭ 31 (-56.94%)
Mutual labels:  hardware
EvoArm
An open-source 3D-printable robotic arm
Stars: ✭ 114 (+58.33%)
Mutual labels:  hardware
BlocksConverter
A PocketMine-MP plugin allows you to convert Minecraft PC maps to MCPE/Bedrock maps or vice-versa.
Stars: ✭ 47 (-34.72%)
Mutual labels:  conversion
xeda
Cross EDA Abstraction and Automation
Stars: ✭ 25 (-65.28%)
Mutual labels:  hardware
edgeai-lab-microcontroller-series
This repository is to share the EdgeAI Lab with Microcontrollers Series material to the entire community. We will share documents, presentations and source code of two demo applications.
Stars: ✭ 15 (-79.17%)
Mutual labels:  hardware
nixiepipe-hardware
Hardware design files and firmware for my Nixie Pipe modules
Stars: ✭ 20 (-72.22%)
Mutual labels:  hardware
APC
Arduino Pinball Controller
Stars: ✭ 27 (-62.5%)
Mutual labels:  hardware
yastack
YAStack: User-space network-stack based on DPDK, FreeBSD TCP/IP Stack, EnvoyProxy
Stars: ✭ 90 (+25%)
Mutual labels:  hardware
rc-headless-transmitter
DIY 2.4 GHz RC transmitter without display, configurable through smartphone or web browser
Stars: ✭ 28 (-61.11%)
Mutual labels:  hardware
spc-player
SNES music player in your browser with original hardware and Arduino.
Stars: ✭ 37 (-48.61%)
Mutual labels:  hardware
chef
Chef configuration management repo for configuring & maintaining the OpenStreetMap servers.
Stars: ✭ 94 (+30.56%)
Mutual labels:  hardware
ansible-role-raspberry-pi
Configures a Raspberry Pi (running Raspbian).
Stars: ✭ 90 (+25%)
Mutual labels:  hardware

embedded-time   CI crates.io docs.rs

embedded-time provides a comprehensive library of Duration and Rate types as well as a Clock abstractions for hardware timers/clocks and the associated Instant type for in embedded systems.

Additionally, an implementation of software timers is provided that work seemlessly with all the types in this crate.

use embedded_time::{duration::*, rate::*};

let micros = 200_000_u32.microseconds();                // 200_000 ╬╝s
let millis: Milliseconds = micros.into();               // 200 ms
let frequency: Result<Hertz,_> = millis.to_rate();      // 5 Hz

assert_eq!(frequency, Ok(5_u32.Hz()));

Motivation

The handling of time on embedded systems is generally much different than that of OSs. For instance, on an OS, the time is measured against an arbitrary epoch. Embedded systems generally don't know (nor do they care) what the real time is, but rather how much time has passed since the system has started.

Drawbacks of the standard library types

Duration

  • The storage is u64 seconds and u32 nanoseconds.
  • This is huge overkill and adds needless complexity beyond what is required (or desired) for embedded systems.
  • Any read (with the exception of seconds and nanoseconds) requires arithmetic to convert to the requested units
  • This is much slower than this project's implementation of what is analogous to a tagged union of time units.

Instant

  • The Instant type requires std.

Drawbacks of the time crate

The time crate is a remarkable library but isn't geared for embedded systems (although it does support a subset of features in no_std contexts). It suffers from some of the same drawbacks as the core::Duration type (namely the storage format) and the Instant struct dependency on std. It also adds a lot of functionally that would seldom be useful in an embedded context. For instance it has a comprehensive date/time formatting, timezone, and calendar support.

Background

What is an Instant?

In the Rust ecosystem, it appears to be idiomatic to call a now() associated function from an Instant type. There is generally no concept of a "Clock". I believe that using the Instant in this way is a violation of the separation of concerns principle. What is an Instant? Is it a time-keeping entity from which you read the current instant in time, or is it that instant in time itself. In this case, it's both.

As an alternative, the current instant in time is read from a Clock. The Instant read from the Clock has the same precision and width (inner type) as the Clock. Requesting the difference between two Instants gives a Duration which can have different precision and/or width.

Overview

The approach taken is similar to the C++ chrono library. Durations and Rates are fixed-point values as in they are comprised of integer and scaling factor values. The scaling factor is a const Fraction. One benefit of this structure is that it avoids unnecessary arithmetic. For example, if the Duration type is Milliseconds, a call to the Duration::integer() method simply returns the integer part directly which in the case is the number of milliseconds represented by the Duration. Conversion arithmetic is only performed when explicitly converting between time units (eg. Milliseconds --> Seconds).

In addition, a wide range of rate-type types are available including Hertz, BitsPerSecond, KibibytesPerSecond, Baud, etc.

A Duration type can be converted to a Rate type and vica-versa.

Definitions

Clock: Any entity that periodically counts (ie an external or peripheral hardware timer/counter). Generally, this needs to be monotonic. A wrapping clock is considered monotonic in this context as long as it fulfills the other requirements.

Wrapping Clock: A clock that when at its maximum value, the next count is the minimum value.

Timer: An entity that counts toward an expiration.

Instant: A specific instant in time ("time-point") read from a clock.

Duration: The difference of two instants. The time that has elapsed since an instant. A span of time.

Rate: A measure of events per time such as frequency, data-rate, etc.

Imports

The suggested use statements are as follows depending on what is needed:

use embedded_time::duration::*;    // imports all duration-related types and traits
use embedded_time::rate::*;        // imports all rate-related types and traits
use embedded_time::clock;
use embedded_time::Instant;
use embedded_time::Timer;

Duration Types

Units Extension
Hours hours
Minutes minutes
Seconds seconds
Milliseconds milliseconds
Microseconds microseconds
Nanoseconds nanoseconds
  • Conversion from Rate types
use embedded_time::{duration::*, rate::*};

Microseconds(500_u32).to_rate() == Ok(Kilohertz(2_u32))
  • Conversion to/from Generic Duration type
use embedded_time::{duration::*};

Seconds(2_u64).to_generic(Fraction::new(1, 2_000)) == Ok(Generic::new(4_000_u32, Fraction::new(1, 2_000)))
Seconds::<u64>::try_from(Generic::new(2_000_u32, Fraction::new(1, 1_000))) == Ok(Seconds(2_u64))

core Compatibility

  • Conversion to/from core::time::Duration

Benchmark Comparisons to core duration type

Construct and Read Milliseconds
use embedded_time::duration::*;

let duration = Milliseconds::<u64>(ms); // 8 bytes
let count = duration.integer();

(the size of embedded-time duration types is only the size of the inner type)

use std::time::Duration;

let core_duration = Duration::from_millis(ms); // 12 bytes
let count = core_duration.as_millis();

(the size of core duration type is 12 B)

Rate Types

Frequency

Units Extension
Mebihertz MiHz
Megahertz MHz
Kibihertz KiHz
Kilohertz kHz
Hertz Hz

Data Rate

Units Extension
MebibytePerSecond MiBps
MegabytePerSecond MBps
KibibytePerSecond KiBps
KiloBytePerSecond KBps
BytePerSecond Bps
MebibitPerSecond Mibps
MegabitPerSecond Mbps
KibibitPerSecond Kibps
KilobitPerSecond kbps
BitPerSecond bps

Symbol Rate

Units Extension
Mebibaud MiBd
Megabaud MBd
Kibibaud KiBd
Kilobaud kBd
Baud Bd
  • Conversion from/to all other rate types within the same class (frequency, data rate, etc.) and base (mega, mebi, kilo, kibi). For example, MiBps (mebibytes per second) --> Kibps (kibibits per second) and MBps (megabytes per second) --> kbps (kilobits per second).

  • Conversion from Duration types

use embedded_time::{duration::*, rate::*};

Kilohertz(500_u32).to_duration() == Ok(Microseconds(2_u32))
  • Conversion to/from Generic Rate type
use embedded_time::rate::*;

Hertz(2_u64).to_generic(Fraction::new(1,2_000)) == Ok(Generic::new(4_000_u32, Fraction::new(1,2_000)))
Hertz::<u64>::try_from(Generic::new(2_000_u32, Fraction::new(1,1_000))) == Ok(Hertz(2_u64))

Hardware Abstraction

  • Clock trait allowing abstraction of hardware timers/clocks for timekeeping.

Timers

  • Software timers spawned from a Clock impl object.
  • One-shot or periodic/continuous
  • Blocking delay
  • Poll for expiration
  • Read elapsed/remaining duration

Reliability and Usability

  • Extensive tests
  • Thorough documentation with examples
  • Example for the nRF52_DK board

Features

  • serde: Enables serde::Deserialize and serde::Serialize implementations for concrete units.

Notes

Some parts of this crate were derived from various sources:

License: MIT OR Apache-2.0

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].