rust-embedded / embedded-hal

A Hardware Abstraction Layer (HAL) for embedded systems
Apache License 2.0
1.88k stars 189 forks source link

Need a unified way to specify frequencies / periods #201

Open Ben-Lichtman opened 4 years ago

Ben-Lichtman commented 4 years ago

A little while back I was trying to create a UART bitbang library.

I took a look at https://crates.io/crates/bitbang-hal however it was incompatible since for nrf51, the Timers usable for a serial port implement From<Duration> but in most other embedded-hal implementors (such as stm32) the timers have their own newtype Hertz struct which is used to set timers (stm32f4xx_hal::time::Hertz).

The overall result is that it is impossible to have a bitbang-hal library that is generic over many types of processors.

If embedded-hal provided a Hertz / Period struct, or possibly required From<Duration> for the Periodic trait, this incompatibility could be eliminated in the downstream crates.

For more info please see https://github.com/sajattack/bitbang-hal/pull/10 - the PR tracking the integration of my port + fixes and the original

Ben-Lichtman commented 3 years ago

see https://github.com/rust-embedded/embedded-hal/issues/211

AlyoshaVasilieva commented 2 years ago

IMO specifying the Time type of Timers as a frequency, like the STM32 HALs do, is incorrect. Requiring From<Duration> or similar seems reasonable since it would actually make the timer trait usable. I also ran into this while writing a driver. In addition to not being able to use timers generically (or it being very hard), the STM32 HALs are effectively limited to 1 second being the longest any timer can run, and cannot handle times like 800ms since it's between 1 and 2 Hz.

(edit: I'll note that the STM32H7 HAL supports using a duration, but not as part of its CountDown impl. Much easier for a user to make a newtype wrapper, though.)

ryankurte commented 2 years ago

requiring From<Duration> would be a neat solve, though, there are some drawbacks to core::time::Duration for embedded use. we could perhaps look to using embedded_time::Duration for this bound?

newAM commented 2 years ago

requiring From<Duration> would be a neat solve, though, there are some drawbacks to core::time::Duration for embedded use. we could perhaps look to using embedded_time::Duration for this bound?

embedded-time is a big dependency. I think the idea of an light-weight duration type is sound; but ideally that functionality would be separated into its own crate to reduce bloat.

embedded-hal compile time:

$ hyperfine --prepare 'cargo clean' 'cargo build --target thumbv7em-none-eabi'
Benchmark #1: cargo build --target thumbv7em-none-eabi
  Time (mean ± σ):     615.6 ms ±  45.0 ms    [User: 531.1 ms, System: 117.1 ms]
  Range (min … max):   586.7 ms … 737.7 ms    10 runs

embedded-time compile time:

$ hyperfine --prepare 'cargo clean' 'cargo build --target thumbv7em-none-eabi'
Benchmark #1: cargo build --target thumbv7em-none-eabi
  Time (mean ± σ):      3.283 s ±  0.088 s    [User: 5.166 s, System: 0.751 s]
  Range (min … max):    3.224 s …  3.483 s    10 runs